Конечно же, есть варианты гораздо проще и изящнее. Списывайте:
import random
def weighted_choice(choices):
u'''
Взвешенный псевдослучайный выбор. Чем выше вес, тем выше шанс выпадения значения.
@param choices: список или кортеж пар вида: ( ('choice', 14), ('choice2', 11), ... (<значение>, <вес> )
'''
total = sum(w for c,w in choices)
r = random.uniform(0, total)
upto = 0
for c, w in choices:
if upto+w > r:
return c
upto += w
assert False, "Shouldn't get here"
Работает вот так:test_choices = ( ('Foo', 8), ('Bar', 3), ('god damn!', 1) )
for i in xrange(10):
print weighted_choice(test_choices)
Вполне логичный способ, при больших значениях веса думаю разница в производительности будет очень заметна.
ОтветитьУдалитьК сожалению, многим людям он в голову не приходит :)
ОтветитьУдалить