[python] Python list iterator behavior and next(iterator)

Consider:

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

So, advancing the iterator is, as expected, handled by mutating that same object.

This being the case, I would expect:

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

to skip every second element: the call to next should advance the iterator once, then the implicit call made by the loop should advance it a second time - and the result of this second call would be assigned to i.

It doesn't. The loop prints all of the items in the list, without skipping any.

My first thought was that this might happen because the loop calls iter on what it is passed, and this might give an independent iterator - this isn't the case, as we have iter(a) is a.

So, why does next not appear to advance the iterator in this case?

This question is related to python list iterator iteration

The answer is


What you see is the interpreter echoing back the return value of next() in addition to i being printed each iteration:

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

So 0 is the output of print(i), 1 the return value from next(), echoed by the interactive interpreter, etc. There are just 5 iterations, each iteration resulting in 2 lines being written to the terminal.

If you assign the output of next() things work as expected:

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

or print extra information to differentiate the print() output from the interactive interpreter echo:

>>> 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

In other words, next() is working as expected, but because it returns the next value from the iterator, echoed by the interactive interpreter, you are led to believe that the loop has its own iterator copy somehow.


It behaves the way you want if called as a function:

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

For those who still do not understand.

>>> 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

As others have already said, next increases the iterator by 1 as expected. Assigning its returned value to a variable doesn't magically changes its behaviour.


I find the existing answers a little confusing, because they only indirectly indicate the essential mystifying thing in the code example: both* the "print i" and the "next(a)" are causing their results to be printed.

Since they're printing alternating elements of the original sequence, and it's unexpected that the "next(a)" statement is printing, it appears as if the "print i" statement is printing all the values.

In that light, it becomes more clear that assigning the result of "next(a)" to a variable inhibits the printing of its' result, so that just the alternate values that the "i" loop variable are printed. Similarly, making the "print" statement emit something more distinctive disambiguates it, as well.

(One of the existing answers refutes the others because that answer is having the example code evaluated as a block, so that the interpreter is not reporting the intermediate values for "next(a)".)

The beguiling thing in answering questions, in general, is being explicit about what is obvious once you know the answer. It can be elusive. Likewise critiquing answers once you understand them. It's interesting...


What is happening is that next(a) returns the next value of a, which is printed to the console because it is not affected.

What you can do is affect a variable with this value:

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

Something is wrong with your Python/Computer.

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

>>> 
0
2
4
6
8

Works like expected.

Tested in Python 2.7 and in Python 3+ . Works properly in both


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to list

Convert List to Pandas Dataframe Column Python find elements in one list that are not in the other Sorting a list with stream.sorted() in Java Python Loop: List Index Out of Range How to combine two lists in R How do I multiply each element in a list by a number? Save a list to a .txt file The most efficient way to remove first N elements in a list? TypeError: list indices must be integers or slices, not str Parse JSON String into List<string>

Examples related to iterator

Iterating over Typescript Map Update row values where certain condition is met in pandas How to iterate (keys, values) in JavaScript? How to convert an iterator to a stream? How to iterate through a list of objects in C++ How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? How to read one single line of csv data in Python? 'numpy.float64' object is not iterable Python list iterator behavior and next(iterator) python JSON only get keys in first level

Examples related to iteration

Is there a way in Pandas to use previous row value in dataframe.apply when previous value is also calculated in the apply? How to loop over grouped Pandas dataframe? How to iterate through a list of dictionaries in Jinja template? How to iterate through an ArrayList of Objects of ArrayList of Objects? Ways to iterate over a list in Java Python list iterator behavior and next(iterator) How to loop through an array containing objects and access their properties recursion versus iteration What is the perfect counterpart in Python for "while not EOF" How to iterate over a JavaScript object?