return 语句中的 for 循环

Posted

技术标签:

【中文标题】return 语句中的 for 循环【英文标题】:for loop inside a return statement 【发布时间】:2014-08-12 11:22:49 【问题描述】:

我正在研究来自 What is the most "pythonic" way to iterate over a list in chunks? 的 Nosklo 的回复,他在那里定义了函数:

def chunker(seq, size):
    return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))

有人可以解释一下在 for 循环之后返回是如何工作的吗? 我尝试执行以下操作:

def chunker2(seq, size):
    for pos in xrange(0, len(seq), size):
    return seq[pos:pos + size]

但我没有得到相同的结果。 请注意,在 Nosklo 示例中,chunker() 被迭代调用,如下例所示:

animals = ['cat', 'dog', 'rabbit', 'duck', 'bird', 'cow', 'gnu', 'fish']
for group in chunker(animals, 3):
    print group

通过添加打印,我注意到后者 for 循环执行了 3 次(它通过 animals 列表),但 chunker 函数中的 for 循环仅执行一次。那么,为什么只有一个返回,我可以看到 3 个打印?

【问题讨论】:

docs.python.org/2/tutorial/… 这不是 for 循环;这是一个生成器表达式。它看起来很像一个 for 循环,这让新手一直认为它是一个循环。见***.com/questions/1756096/…和legacy.python.org/dev/peps/pep-0289 非常感谢!我会检查这些链接。 +1 用于询问并合理地呈现用户到目前为止所理解的内容。我希望我可以再给一个 +1 来尝试学习最“pythonic”的做事方式。祝你学习 python 好运,还有更多关于 *** 的问题。 我不确定我是否完全理解。所以,chunker 是生成器,对吧?在我的示例中,它被调用了 3 次,每次都返回不同的值。第一次,组是[猫,狗,兔子]。我的问题是针对以下迭代:下次调用 chunker 时,“pos”如何成为列表的第 4 个索引?我唯一的解释是,列表的完整分段只完成一次,每次我再次调用 chunker 时,我都会得到一个新的分段。我的理解(或多或少)正确吗?谢谢! 【参考方案1】:

nosklo chunker 函数的返回值称为生成器,是一个在迭代时会生成值的对象。在这种情况下,生成器是使用 generator expression 创建的,这是括号之间不可分割的一段代码:(seq[pos:pos + size] for pos in xrange(0, len(seq), size))

>>> def chunker(seq, size):
...     return (seq[pos:pos + size] for pos in xrange(0, len(seq), size))
... 
>>> result = chunker([1, 2, 3], 2)
>>> print(result)
<generator object <genexpr> at 0x10581e1e0>
>>> next(result)
[1, 2]
>>> next(result)
[3]

关于调用什么,我们可以这样重写循环代码以更好地查看:

>>> generator = chunker(animals, 3)
>>> for chunk in generator:
...     print chunk
... 
['cat', 'dog', 'rabbit']
['duck', 'bird', 'cow']
['gnu', 'fish']    

chunker 函数只被调用一次并返回生成器对象,我们将其存储在generator 变量中。然后for 循环仅适用于这个generator 对象并调用它3 次。

为了能够打印此生成器的实际调用,您必须在生成器表达式 (seq[pos:pos + size] for pos in xrange(0, len(seq), size)) 中包含 print 语句,这是不允许的。但是我们可以使用yield 语句将这个生成器表达式重写为普通的generator function,这是一种更详细但也更通用的生成器形式,我们可以在其中包含print 语句,它会按照您最初的预期工作:

>>> def chunker2(seq, size):
...     for pos in xrange(0, len(seq), size):
...         print('chunker2 generator called')
...         yield seq[pos:pos + size]
... 
>>> for group in chunker2(animals, 3):
...     print group
... 
chunker2 generator called
['cat', 'dog', 'rabbit']
chunker2 generator called
['duck', 'bird', 'cow']
chunker2 generator called
['gnu', 'fish']

这里的 chunker2 函数本身就是真正的生成器,被调用了 3 次。

【讨论】:

谢谢。所以这意味着在 Nosklo 示例中,“下一个”对应于循环中的不同迭代 for group in chunker(animals, 3): @user3764177 正确,next 函数从可迭代对象中获取下一项,与 for 循环的一次迭代相同。

以上是关于return 语句中的 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

Python怎么return后让循环继续运行?

return break 和continue在for循环中的不同作用

return break 和continue在for循环中的不同作用

for循环中缺少return语句

for循环中的java rpc

举例说明c语言中的中断语句break,continue,return的区别及相同之处