Here's a version I just wrote:
import random
"""
iterator is an Iterator/Generator object for a streamand N >= k
"""
def reservoir(iterator, return_count): arr = [] current = 0 for item in iterator: if current < return_count: arr.append(item) else: rand = random.randint(0, current) if rand <= return_count: arr[rand] = item current += 1 return arr
Once I read it, I noticed that it is strikingly similar to an inside out Fisher-Yates Shuffle (which is how you you return a random permutation of a list from a list)That would look like:
import random
def shuffle(cards): deck = [] current = 0 for card in cards: rand = random.randint(0, current) if rand != current: deck.append(deck[rand]) deck[rand] = card return deckThat said, with reservoir, you won't have a random permutation of the elements. And shuffle uses extra memory if the length of the card pile is very long, and you only need some k cards.
Thus:
import random
def resshuffle(iterator, return_count):arr = []
current = 0
while (current < return_count):
rand = random.randint(0, current)
if current < return_count:
arr.append(arr[rand])
arr[rand] = iterator.next()
current += 1
for item in iterator:
if rand <= return_count:
arr[rand] = item
current += 1
return arr
No comments:
Post a Comment