我有一个函数alternate_all(*args)中的生成器列表,在列表中的每个生成器之间交替打印第一项、第二项、.等等,直到所有生成器用完为止。
我的代码一直工作到生成器耗尽,一旦发生StopIteration,它就停止打印,当我希望它继续使用其余的生成器时,忽略耗尽的生成器:
def alternate_all(*args):
iter_list = []
for iterable in args:
iter_list.append(iter(iterable))
try:
while True:
for iterable in iter_list:
val = next(iter_list[0])
iter_list.append(iter_list.pop(0))
yield val
except StopIteration:
pass
if __name__ == '__main__':
for i in alternate_all('abcde','fg','hijk'):
print(i,end='')我的产出是:
afhbgic当它应该是:
afhbgicjdke我怎么能让这个无视耗尽的发电机?我不喜欢使用迭代工具,保持相同的结构。
发布于 2021-10-28 04:54:09
这个很管用。我试图了解您的原始代码是如何工作的(尽管为了简单起见,我确实用列表理解替换了您的第一个循环)。
def alternate_all(*args):
iter_list = [iter(arg) for arg in args]
while iter_list:
i = iter_list.pop(0)
try:
val = next(i)
except StopIteration:
pass
else:
yield val
iter_list.append(i)代码的主要问题是try/except在循环之外,这意味着第一个耗尽的迭代器将退出循环。相反,您希望在循环中捕获StopIteration,这样您就可以继续运行,并且循环应该继续运行,而iter_list中仍然有任何迭代器。
发布于 2021-10-28 04:40:34
迭代工具-菜谱roundrobin,直接从itertools文档中得到,怎么样?不过,你最终还是会使用itertools.cycle和itertools.islice,但不确定这是否会破坏交易。
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
num_active = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while num_active:
try:
for next in nexts:
yield next()
except StopIteration:
# Remove the iterator we just exhausted from the cycle.
num_active -= 1
nexts = cycle(islice(nexts, num_active))https://stackoverflow.com/questions/69748145
复制相似问题