【问题标题】:Python nested for loop Vs generator for repeatedly iterating over a list provided by a functionPython 嵌套 for 循环 Vs 生成器,用于重复迭代函数提供的列表
【发布时间】:2025-12-26 00:45:20
【问题描述】:

问题很简单,我有一个返回列表的方法。 我想遍历这个列表中的每个项目,一旦完成, 调用该方法接收一个新列表,然后重复。

目前,我的代码如下所示:

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():
        ...

虽然我之前的尝试看起来在某些方面更好,但我目前的方法有一些“优势”:

  • 如果 Condition 设置为 false,则循环结束而无需将 break 退出 for 循环。
    • 上述原因的扩展,可以访问 Condition 的方法可以结束循环而不遍历所述列表中的所有其他项目,或者在 for 循环中执行特殊检查。
  • 第一种方法允许在需要时跳过循环中的项目。
  • 还少了一级缩进。这比其他任何东西都更虚荣,但考虑到实际代码是类方法的一部分,缩进级别已经相当高了。

至少可以说,我困惑哪个更合适。它们似乎都有独特的优点和缺点,所以如果有人知道最正确和最pythonic的方法,我将不胜感激。

【问题讨论】:

    标签: for-loop iterator python


    【解决方案1】:

    我建议你使用一些迭代器

    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() 的结果,直到它返回哨兵。

    itertools.chain.from_iterable 返回一个将原始迭代器展平的迭代器,它将生成第一个迭代器生成的列表中的值。

    我认为这为您提供了您的方法的大部分优点,但风格更简洁。

    【讨论】:

    • 这很好用。尽管第一行最初看起来很神秘,但这是一个更好的解决方案。我看到的唯一问题是,当需要将参数传递给可调用对象时。有关如何解决此问题的任何建议?
    • @SingularityCat,有两个选项。您可以使用 functools.partial 结合函数和参数来创建新函数。或者你可以写一个生成器。
    【解决方案2】:

    这里有意见的余地,但就我而言,第二种方法的简洁性使其成为明显的胜利。特别是如果 item 变量的使用仅限于循环内,我每次都会选择 for / in 语法。有一些问题,涉及循环中的缓冲区和状态更改,我选择不使用 for / in。但这是少数。

    【讨论】: