Python-从列表中选择随机对象

Python-从列表中选择随机对象,python,list,random,python-2.7,Python,List,Random,Python 2.7,我有一个对象列表“p”,每个对象都有一个数字“a”(例如p[3].a=5)。我想从列表中选择随机对象,选择对象的概率与其a值成正比,即选择a=5的对象的概率是选择a=1的对象的概率的五倍。如何使用Python/Pylab/Numpy实现这一点 谢谢大家! 这对整数计数有效,但对大计数无效 c = collections.Counter({k:k.a for k in stuff}) random.choice(list(c.elements())) 这对整数计数有效,但对大计数无效 c = c

我有一个对象列表“p”,每个对象都有一个数字“a”(例如p[3].a=5)。我想从列表中选择随机对象,选择对象的概率与其a值成正比,即选择a=5的对象的概率是选择a=1的对象的概率的五倍。如何使用Python/Pylab/Numpy实现这一点


谢谢大家!

这对整数计数有效,但对大计数无效

c = collections.Counter({k:k.a for k in stuff})
random.choice(list(c.elements()))

这对整数计数有效,但对大计数无效

c = collections.Counter({k:k.a for k in stuff})
random.choice(list(c.elements()))

这里有一个更有效的方法

import random

def weighted_choice(items):
    # check if no items exist
    if not items:
        return None

    # compute total of all weights
    total = sum(item.weight for item in items)

    # select a random point within the total
    selection = random.randint(0, total - 1)

    # find the corresponding item
    count = 0
    for item in items:
        count += item.weight
        if selection < count:
            return item
随机导入
def加权_选项(项目):
#检查是否不存在任何项目
如果不是项目:
一无所获
#计算所有权重的总和
总计=总和(项目中项目的项目重量)
#在总数中选择一个随机点
选择=random.randint(0,总计-1)
#找到相应的项目
计数=0
对于项目中的项目:
计数+=项目重量
如果选择<计数:
退货项目

这里有一种更有效的方法

import random

def weighted_choice(items):
    # check if no items exist
    if not items:
        return None

    # compute total of all weights
    total = sum(item.weight for item in items)

    # select a random point within the total
    selection = random.randint(0, total - 1)

    # find the corresponding item
    count = 0
    for item in items:
        count += item.weight
        if selection < count:
            return item
随机导入
def加权_选项(项目):
#检查是否不存在任何项目
如果不是项目:
一无所获
#计算所有权重的总和
总计=总和(项目中项目的项目重量)
#在总数中选择一个随机点
选择=random.randint(0,总计-1)
#找到相应的项目
计数=0
对于项目中的项目:
计数+=项目重量
如果选择<计数:
退货项目
我建议使用

您只需使用断点构建一次列表。然后,您可以将它与非常快速的对分算法一起使用,只要您愿意

最后一个循环只是为了演示结果

编辑:获取断点的另一种方法(我不喜欢for循环):

我建议使用

您只需使用断点构建一次列表。然后,您可以将它与非常快速的对分算法一起使用,只要您愿意

最后一个循环只是为了演示结果

编辑:获取断点的另一种方法(我不喜欢for循环):


不带
计数器的等效方法
随机选择([x代表x,p代表i,范围(x.a)])
不带
计数器的等效方法
随机选择([x代表x,p代表i,范围(x.a)])