【问题标题】:Continue until all iterators are done Python继续,直到所有迭代器都完成 Python
【发布时间】:2015-07-18 17:49:59
【问题描述】:

我无法使用 itertools

所以编码看起来很简单,但我很难考虑让生成器保持运行直到所有迭代都被完全处理的算法。

函数的想法是像这样将2个迭代作为参数......

(['a', 'b', 'c', 'd', 'e'], [1,2,5])

它所做的就是产生这些值......

a, b, b, c, c, c, c, c

但是,如果第二个可迭代对象首先用完元素,该函数只会将剩余的值迭代一次......

所以剩下的值会像这样迭代:

d, e

def iteration(letters, numbers):
    times = 0
    for x,y in zip(letters, numbers):
        try:
            for z in range(y):
                yield x
        except:
            continue

[print(x) for x in iteration(['a', 'b', 'c', 'd'], [1,2,3])]

我很难忽略第一个 StopIteration 并继续完成。

【问题讨论】:

  • 嗯,这也是我遇到问题的地方。我不知道如何让迭代同时继续,以便 a 获得 1 值,b 获得 2 值。
  • d 和 e 会发生什么?
  • 当带有数字的迭代用完时,第一个中剩余的迭代应该每次只产生一次。
  • 如果您不能使用 itertools,请阅读函数 itertools.zip_longest 的文档。那里有一段代码,上面写着“相当于” zip_longest。这是您的解决方案,除非您需要重新发明轮子。在任何情况下,您都不能使用 zip,因为它会在其中一个可迭代对象用完时停止迭代。

标签: python generator iterable


【解决方案1】:

next 使用默认值1,以便您至少打印一次字母:

def iteration(letters, numbers): 
     # create iterator from numbers
    it = iter(numbers)
    # get every letter
    for x in letters:
        # either print in range passed or default range of 1
        for z in range(next(it, 1)):
            yield x

输出:

In [60]: for s in iteration(['a', 'b', 'c', 'd', 'e'], [1,2,5]):
   ....:     print(s)
   ....:     
a
b
b
c
c
c
c
c
d
e

【讨论】:

  • 感谢这帮助了很多人,很容易理解我哪里出错了。我不知道如果迭代失败,您可以为其分配默认值。
  • @FlyingBumble,没问题,这是一个有趣的问题。是的,next 的第二个值是一个默认值,它将避免 StopIteration 并且还允许我们至少查看每个字符串一次。
【解决方案2】:

阅读 zip() 的文档。它说: “当您不关心来自较长可迭代对象的尾随、不匹配值时,zip() 应该只用于不等长度的输入。如果这些值很重要,请改用 itertools.zip_longest()。”

【讨论】:

    猜你喜欢
    • 2021-11-26
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多