这个问题在这里已有答案:
choices = [a,a,a,a,b,b,c]
random.choice(choices)
正如你所看到的那样,最有可能被选中,但有更好/更短的方式吗?
如果使用choices
而不是choice
,则可以为每个元素指定权重。
random.choices([a,b,c], [4,2,1])
第二个参数是第一个参数中每个元素的相对权重。例如,在下面你可以看到a
的选择大约是b
的两倍,大约是c
的四倍。
>>> import collections, random
>>> collections.Counter(random.choices('abc', [4,2,1], k=100))
Counter({'a': 58, 'b': 25, 'c': 17})
如果您不使用Python 3.6+(支持random.choices
中的权重),您可以构建一个群体:
import random
a, b, c = 'abc'
weighted = [(a, 4), (b, 2), (c, 1)]
population = [x for x, weight in weighted for _ in range(weight)]
random.choice(population)
如果您担心大重量值的性能,可以使用itertools.accumulate
和bisect
:
import bisect
import itertools
import random
choices = ['a', 'b', 'c']
weights = [4, 2, 1]
cumulative_weights = list(itertools.accumulate(weights))
print(choices[bisect.bisect(cumulative_weights, random.random() * cumulative_weights[-1])])