[英]Randomly sample between multiple generators?
我正在尝试随机迭代多个生成器,并通过从可用生成器列表中删除它们来跳过那些已经耗尽的生成器。 然而,CombinedGenerator 并没有像它应该的那样调用自己来切换生成器。 相反,当较小的迭代器用尽时,它会抛出一个 StopIteration。 我错过了什么?
以下作品:
gen1 = (i for i in range(0, 5, 1))
gen2 = (i for i in range(100, 200, 1))
list_of_gen = [gen1, gen2]
print(list_of_gen)
list_of_gen.remove(gen1)
print(list_of_gen)
list_of_gen.remove(gen2)
print(list_of_gen)
其中每个生成器都通过它们的引用被删除。
但在这里它没有:
import random
gen1 = (i for i in range(0, 5, 1))
gen2 = (i for i in range(100, 200, 1))
total = 105
class CombinedGenerator:
def __init__(self, generators):
self.generators = generators
def __call__(self):
generator = random.choice(self.generators)
try:
yield next(generator)
except StopIteration:
self.generators.remove(generator)
if len(self.generators) != 0:
self.__call__()
else:
raise StopIteration
c = CombinedGenerator([gen1, gen2])
for i in range(total):
print(f"iter {i}")
print(f"yielded {next(c())}")
正如@Tomerikoo 提到的,您基本上是在创建自己的生成器,最好实现__next__
,这是更清洁和 pythonic 的方式。
上面的代码可以用下面的行来修复。
def __call__(self):
generator = random.choice(self.generators)
try:
yield next(generator)
except StopIteration:
self.generators.remove(generator)
if len(self.generators) != 0:
# yield your self.__call__() result as well
yield next(self.__call__())
else:
raise StopIteration
首先,为了修复您当前的代码,您只需要通过更改行来匹配您创建的模式:
self.__call__()
至:
yield next(self.__call__())
然后,我将对您的原始代码进行一些小改动:
__call__
并调用 object,不如实现__next__
并简单地在 object 上调用next
似乎更合理。remove
。class CombinedGenerator:
def __init__(self, generators):
self.generators = generators
def __next__(self):
while self.generators:
i = random.choice(range(len(self.generators)))
try:
return next(self.generators[i])
except StopIteration:
del self.generators[i]
raise StopIteration
c = CombinedGenerator([gen1, gen2])
for i in range(total):
print(f"iter {i}")
print(f"yielded {next(c)}")
一个不错的奖励是将其添加到您的 class 中:
def __iter__(self):
return self
然后,您可以直接在 object 本身上进行迭代,并且您不需要total
变量:
for i, num in enumerate(c):
print(f"iter {i}")
print(f"yielded {num}")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.