for return语句中的for循环

时间:2014-06-22 06:19:18

标签: python for-loop return

我在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))

有人可以解释一下,当循环后面的返回是如何工作的吗? 我试着做以下事情:

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个印刷品?

1 个答案:

答案 0 :(得分:3)

nosklo chunker函数的返回值称为生成器,它是在迭代时生成值的对象。在这种情况下,生成器是使用generator expression创建的,generator function是括号中不可分割的代码:(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次。

为了能够打印此生成器的实际调用,您必须在生成器表达式print中包含(seq[pos:pos + size] for pos in xrange(0, len(seq), size))语句,这是不允许的。但是我们可以使用yield语句将此生成器表达式重写为普通{{3}},这是一种更详细但也更通用的生成器形式,我们可以在其中包含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次。