2013-05-29 148 views
104

考虑:Python列表迭代器的行为和未来(迭代器)

>>> 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在这种情况下似乎没有推进迭代器?

回答

137

你看到的是解释回显的除了next()i的返回值被打印在每个迭代:

>>> 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)输出,1回报从next()得到的值,由交互式解释器回应等等。只有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()按预期工作,但是因为它会从迭代器返回下一个值,并由交互式解释器响应,您将被导入相信循环以某种方式具有自己的迭代器复制。

+8

我不知道从解释这种行为。我很高兴我发现,在解决一些真正的问题的同时,在浪费了大量时间之前,我还想知道它。 – brandizzi

+3

... \ *死亡*。最糟糕的是,我可以记得在一周前向某人提及这种解释行为。 – lvc

+0

有趣。我在a:next(a)中尝试了我;打印我并认为我会跳到1并打印1,3,5,7,9。但仍然是0,2,4,6,8。为什么? – user2290820

2

您的Python /计算机出现问题。

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

>>> 
0 
2 
4 
6 
8 

像预期的那样工作。

使用Python 2.7和Python 3+进行测试。正常工作在这两个

+5

,我得到了相同的结果@lvc(仅在IDLE然而,当作为脚本我得到这个执行)) – jamylak

+3

@Inbar Rose仅当您以脚本运行时才有效。 – thecoder16

+0

它是通过交互式shell放置代码的行为。如果函数返回而不使用值,解释将打印到shell作为调试输出 – Reishin

10

发生了什么事是next(a)返回a的下一个值,该值将打印到控制台,因为它不受影响。

你可以做什么是影响一个变量,这个值:

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

我觉得现有的答案有点混乱,因为他们只间接地表明了代码示例基本神秘的事: * “打印我”和“下一个(a)”导致他们的结果被打印。

因为他们印刷交替原始序列的元素,这是意想不到的是,“未来(一)”语句是印刷,它看起来好像“打印我”语句打印所有值。

有鉴于此,将变量“next(a)”的结果赋值给一个变量禁止打印其结果,这样就可以打印出“i”循环变量的替代值。同样,使“印刷”声明发出更明确的内容也可以消除歧义。

(因为这个问题的答案是具有评价为块的示例代码,使得解释器不是“下一个的(a)”。报告了中间值的一种现有答案反驳了其他)一般来说,在回答问题时出乎意料的是,一旦你知道答案,就会明确表明什么是显而易见的。它可能难以捉摸。同样,一旦你了解他们就会批评答案。这很有趣......

1

它的行为你想,如果作为函数调用的方式:

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