Конечно же, есть варианты гораздо проще и изящнее. Списывайте:
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)
Вполне логичный способ, при больших значениях веса думаю разница в производительности будет очень заметна.
ОтветитьУдалитьК сожалению, многим людям он в голову не приходит :)
ОтветитьУдалить