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 循环的主要内容,如果未能解决你的问题,请参考以下文章
return break 和continue在for循环中的不同作用