python - 在多个生成器之间随机采样?
问题描述
我正在尝试随机迭代多个生成器,并通过从可用生成器列表中删除它们来跳过那些已经耗尽的生成器。然而,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
推荐阅读
- javascript - 带有刀片 SourceMap 的 laravel 项目错误
- javascript - 通过异步调用在D3中调用JSON后如何保留数据?
- chocolatey - 如何查看用于使用 Chocolatey 安装已安装包的参数?
- ada - Ada 编译警告
- universe - 如何选择 TCL 中的值标记字符?
- hash - 意外失败与 :exists in raku
- unit-testing - 获取当前的 URLCodeception 并打印它
- javascript - 如何按对象值对对象数组进行排序?
- ios - 如何在 Nativescript 中翻译 actionItem
- java - GCP-PUBSUB:-sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径