2014-10-16 45 views
1

我正在嘗試使用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

你所說的「挑」是什麼意思?你只是在洗牌而不是選擇一個項目。 http://stackoverflow.com/questions/14992521/python-weighted-random可能有幫助嗎? – geoffspear 2014-10-16 17:04:00

+1

可能會更容易添加額外的名稱,你想多出來的名字 – 2014-10-16 17:05:34

+1

另請參見http://programmers.stackexchange.com/questions/233541/how-to-implement-a-weighted-shuffle – aruisdante 2014-10-16 17:06:28

回答

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)) 

根據您的必需品,這是更好地建立一個發電機...

0

這是一個簡單的變種,將做你想做的。需要注意的是幾乎肯定更有效的方式來做到這一點,因爲這是目前爲O(n^2)在運行時間和使用N * m,其中ñ輸入人口規模和最大內存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'] 
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