Python 嵌套 for 循环与生成器在函数返回列表时的多次迭代

2 投票
2 回答
2101 浏览
提问于 2025-04-17 05:13

这个问题其实很简单,我有一个方法可以返回一个列表。我想要遍历这个列表里的每一个项目,等遍历完了之后,再调用这个方法来获取一个新的列表,然后重复这个过程。

目前,我的代码大概是这样的:

generator = iter([])
while Condition:
    try:
        item = next(generator)
    except StopIteration:
        generator = iter(list_returining_method())
        item = next(generator)
    ...

不过之前,我是用嵌套的 for 循环。

while Condition:
    for item in list_returining_method():
        ...

虽然我之前的写法在某些方面看起来更好,但我现在的方法有一些“优点”:

  • 如果条件设置为假,循环就会结束,而不需要在 for 循环中使用 break 来退出。
    • 基于上面的原因,能够访问条件的方法可以在不遍历列表中所有其他项目的情况下结束循环,或者不需要在 for 循环中实现特殊检查。
  • 第一种方法允许在循环中跳过某些项目,如果有需要的话。
  • 缩进层级也少了一层。这主要是为了美观,但考虑到实际代码已经是类方法的一部分,缩进层级已经挺高了。

总之,我对哪种方法更合适感到有些“困惑”。它们似乎都有独特的优缺点,所以如果有人知道最正确和符合 Python 风格的方法,我会非常感激。

2 个回答

1

这里可以有不同的看法,但我觉得第二种方法简单明了,明显更好。特别是当item这个变量只在循环内部使用的时候,我每次都会选择用for / in的写法。我遇到过一些问题,比如在循环中涉及到缓冲区和状态变化的情况,那时候我选择不使用for / in。但这种情况很少。

2

我建议你使用一些迭代器。

items = itertools.chain.from_iterable( iter(list_returning_method, None) )

for item in items:
    # do something with item
    print item

    if not Condition:
       break

iter(callable, sentinel) 会返回一个迭代器,这个迭代器会一直调用你给的函数(callable),直到它返回一个特定的值(sentinel)为止。

itertools.chain.from_iterable 会返回一个迭代器,它可以把原来的迭代器中的内容“压平”,也就是说,它会把第一个迭代器生成的列表里的值一个一个地输出出来。

我觉得这样做可以让你在保持大部分原有方法优点的同时,代码看起来更简洁。

撰写回答