import random class RandomCycler: def __init__(self, source): if len(source) == 0: raise Exception("Can't create RandomCycler from an empty collection") self.all_items = list(source) self.next_items = [] def sample(self, count: int): shuffle = lambda l: random.sample(l, len(l)) out = [] while count > 0: if count >= len(self.all_items): out.extend(shuffle(list(self.all_items))) count -= len(self.all_items) continue n = min(count, len(self.next_items)) out.extend(self.next_items[:n]) count -= n self.next_items = self.next_items[n:] if len(self.next_items) == 0: self.next_items = shuffle(list(self.all_items)) return out def __next__(self): return self.sample(1)[0]