由于在 Python 3.5 中没有 random.choices() 函数,是否有替代方法?
由于在 Python 3.5 中没有 random.choices() 函数,是否有替代方法?
按照Mark Dickinson的建议,将代码从Python 3.6复制到中。
from itertools import accumulate as _accumulate, repeat as _repeat
from bisect import bisect as _bisect
import random
def choices(population, weights=None, *, cum_weights=None, k=1):
"""Return a k sized list of population elements chosen with replacement.
If the relative weights or cumulative weights are not specified,
the selections are made with equal probability.
"""
n = len(population)
if cum_weights is None:
if weights is None:
_int = int
n += 0.0 # convert to float for a small speed improvement
return [population[_int(random.random() * n)] for i in _repeat(None, k)]
cum_weights = list(_accumulate(weights))
elif weights is not None:
raise TypeError('Cannot specify both weights and cumulative weights')
if len(cum_weights) != n:
raise ValueError('The number of weights does not match the population')
bisect = _bisect
total = cum_weights[-1] + 0.0 # convert to float
hi = n - 1
return [population[bisect(cum_weights, random.random() * total, 0, hi)]
for i in _repeat(None, k)]
choices
函数!我并没有完全爱上Venkatesh Mondi的回答,但它是完全可用的。
import random
def random_choices(population, weights=None, k=1):
"""
This function achieves the same result.
If weights is not provided, it returns a list of k random choices made using random.
choice with no weighting. If weights is provided, it first normalizes the weights by
dividing each weight by the sum of all the weights, and then returns a list of k random
choices made using random.choice with the normalized weights.
"""
if weights is None:
return [random.choice(population) for _ in range(k)]
total = sum(weights)
weights = [weight/total for weight in weights]
cumulative_weights = [sum(weights[:i+1]) for i in range(len(weights))]
return [population[cumulative_weights.index(next(x for x in cumulative_weights if x >= random.random()))] for _ in range(k)]
#note you may also do something like:
return population[weights.index(random.choice(weights))]
print(random_choices(population, weights=weights, k=1)[0])
这是一个我已经使用了一段时间的替代方案,我不确定是否有人先写过它或者是我写的。
random.choices
是用 Python 编写的,因此您可以将该方法的代码简单地复制到您的代码库中。 - Mark Dickinson