我正在尝试使用Python创建一个程序,该程序从列表中获取名称,并以随机顺序显示列表中的名称,同时仅使用每个名称一次。我已经做到了这一点,并使用以下代码:
import random
drivers = [
"John Doe",
"Bill Smith",
"Trent Baxter",
"Ray Olson",
]
random.shuffle(drivers)
for position in drivers:
print(position)
OUPUT:
Bill Smith
John Doe
Ray Olson
Trent Baxter
这样可行,但是我想让程序为每个名称指定值以使它们更多,或者更不可能被选中,同时仍然只选择一次名称。
答案 0 :(得分:0)
这是一个简单的变体,可以做你想要的。请注意,几乎可以肯定很多更有效的方法,因为它在运行时当前 O(n ^ 2)并使用 n * m < / strong>最大内存,其中 n 是输入填充大小, m 是平均权重,因为它构建的列表具有每个权重的输入列表值的一个副本。
import random
import itertools
def random_weighted_shuffle(input_population):
'''
:param input_population: {name:weight}, where weight is the 'number of chances' that this particular name will be drawn
'''
out_list = []
while input_population:
lotto_list = list(itertools.chain.from_iterable([name]*weight for name, weight in input_population.iteritems()))
selection = lotto_list[random.randint(0,len(lotto_list)-1)]
del input_population[selection]
out_list.append(selection)
return out_list
非常重要说明:如上所述,此方法对输入字典具有破坏性。
用法:
>>> random_weighted_shuffle({'a':10,'b':2,'c':5})
['a', 'b', 'c']
>>> random_weighted_shuffle({'a':10,'b':2,'c':5})
['a', 'c', 'b']
>>> random_weighted_shuffle({'a':10,'b':2,'c':5})
['b', 'c', 'a']
>>> random_weighted_shuffle({'a':10,'b':2,'c':5})
['c', 'a', 'b']
>>> random_weighted_shuffle({'a':10,'b':2,'c':5})
['a', 'c', 'b']
答案 1 :(得分:0)
你的问题可以用不同的方式解释。如果你的意思是挑选元素的数量没有固定,那么每个元素都有自己被挑选的概率,并且所有选择都是独立发生的,而不是以这种方式解决任务(看起来像 O(n) )强>):
from scipy.stats import bernoulli
probs = [0.2, 0.5, 0.7, 0.1]
for i, d in enumerate(drivers):
if bernoulli.rvs(probs[i], size=1)[0]: # generates a list of length 1 containing Bernoulli random variable
print d
答案 2 :(得分:0)
仅使用标准模块进行解答:
from itertools import accumulate
from random import uniform
class ProbItem(object):
def __init__(self, value, prob):
self.value = value
self.prob = prob
def pick(items):
accum = list(accumulate(item.prob for item in items))
rand = uniform(0, accum[-1])
for i, prob in enumerate(accum):
if rand < prob:
return items.pop(i).value
drivers = [
ProbItem("John Doe", 23.7),
ProbItem("Bill Smith", 17),
ProbItem("Trent Baxter", 12.43),
ProbItem("Ray Olson", 9.99),
]
while (drivers):
print(pick(drivers))
根据您的需要,建造发电机会更好......