I have a program where I'm keeping track of the success of various things using collections.Counter
— each success of a thing increments the corresponding counter:
import collections
scoreboard = collections.Counter()
if test(thing):
scoreboard[thing]+ = 1
Then, for future tests, I want to skew towards things which have generated the most success. Counter.elements()
seemed ideal for this, since it returns the elements (in arbitrary order) repeated a number of times equal to the count. So I figured I could just do:
import random
nextthing=random.choice(scoreboard.elements())
But no, that raises TypeError: object of type 'itertools.chain' has no len(). Okay, so random.choice
can't work with iterators. But, in this case, the length is known (or knowable) — it's sum(scoreboard.values())
.
I know the basic algorithm for iterating through a list of unknown length and fairly picking an element at random, but I suspect that there's something more elegant. What should I be doing here?