Python 列出迭代器行为和 next (迭代器)

考虑一下:

>>> lst = iter([1,2,3])
>>> next(lst)
1
>>> next(lst)
2

因此,正如预期的那样,推进迭代器是通过变更相同的对象来处理的。

在这种情况下,我期望:

a = iter(list(range(10)))
for i in a:
print(i)
next(a)

跳过每一个第二个元素: 对 next的调用应该提前迭代器一次,然后循环的隐式调用应该提前迭代器第二次——第二次调用的结果将被分配给 i

循环打印列表中项目的 所有,而不跳过任何项目。

我的第一个想法是,这可能会发生,因为循环在传递的内容上调用 iter,这可能会产生一个独立的迭代器——但事实并非如此,因为我们有 iter(a) is a

那么,在这种情况下,为什么 next似乎没有提前迭代器呢?

266712 次浏览

你的 Python/电脑出问题了。

a = iter(list(range(10)))
for i in a:
print(i)
next(a)


>>>
0
2
4
6
8

和预期的一样。

在 Python 2.7和 Python 3 + 中进行了测试

你看到的是 翻译在每次迭代中除了打印 i之外,还回传 next()的返回值:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    next(a)
...
0
1
2
3
4
5
6
7
8
9

所以 0print(i)的输出,1next()的返回值,由交互式解释器回显,等等。只有5个迭代,每个迭代导致向终端写入2行。

如果你分配 next()的输出,事情就会按预期运行:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    _ = next(a)
...
0
2
4
6
8

或打印 额外的信息,以区分 print()输出和交互式解释器回声:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print('Printing: {}'.format(i))
...    next(a)
...
Printing: 0
1
Printing: 2
3
Printing: 4
5
Printing: 6
7
Printing: 8
9

换句话说,next()正在按照预期的方式工作,但是因为它从迭代器返回下一个值,并由交互式解释器回显,所以会让您相信循环以某种方式拥有自己的迭代器副本。

现在的情况是,next(a)返回 a 的下一个值,这个值被打印到控制台,因为它不受影响。

你能做的就是用这个值影响一个变量:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    b=next(a)
...
0
2
4
6
8

我发现现有的答案有点令人困惑,因为它们只是间接地表明了代码示例中基本的令人困惑的事情: 都有 * “ print i”和“ next (a)”导致了它们的结果被打印出来。

由于它们打印的是原始序列的交替元素,而且出乎意料的是“ next (a)”语句正在打印,看起来好像“ print i”语句正在打印所有的值。

在这种情况下,将“ next (a)”的结果赋给一个变量会抑制其结果的打印,因此只打印“ i”循环变量的替代值就变得更加清楚了。类似地,使“ print”语句发出更加独特的内容也可以消除歧义。

(其中一个现有的回答驳斥了其他的回答,因为这个回答将示例代码作为一个块进行计算,所以解释器不会报告“ next (a)”的中间值。)

一般来说,回答问题的诱人之处在于,一旦你知道了答案,你就会清楚地知道什么是显而易见的。有时候很难捉摸。同样地,一旦你理解了答案,你也会批评它们。有意思..。

如果作为函数调用,它的行为如您所愿:

>>> def test():
...     a = iter(list(range(10)))
...     for i in a:
...         print(i)
...         next(a)
...
>>> test()
0
2
4
6
8

对于那些仍然不明白。

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    next(a)
...
0 # print(i) printed this
1 # next(a) printed this
2 # print(i) printed this
3 # next(a) printed this
4 # print(i) printed this
5 # next(a) printed this
6 # print(i) printed this
7 # next(a) printed this
8 # print(i) printed this
9 # next(a) printed this

正如其他人已经说过的,next按照预期将迭代器增加1。将其返回值赋给变量并不会神奇地改变其行为。