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 не появляется, чтобы продвигать итератор в этом случае?

Ответ 1

То, что вы видите, это интерпретатор, возвращающий обратно возвращаемое значение 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

So 0 - это вывод print(i), 1 возвращаемого значения из next(), отображаемого интерактивным интерпретатором и т.д. Всего есть 5 итераций, каждая итерация приводит к тому, что две строки записываются в терминал.

Если вы назначаете вывод 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() работает так, как ожидалось, но поскольку он возвращает следующее значение из итератора, отраженное интерактивным интерпретатором, вы вынуждены полагать, что цикл имеет свою собственную копию итератора как-то.

Ответ 2

Что происходит, так это то, что next(a) возвращает следующее значение a, которое печатается на консоли, потому что оно не изменяется.

Что вы можете сделать, это повлиять на переменную с этим значением:

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

Ответ 3

Я нахожу существующие ответы немного запутанными, потому что они лишь косвенно указывают на существенную мистификацию в примере кода: оба: "print i" и "next (a)" вызывают их результаты для печати. ​​

Поскольку они печатают чередующиеся элементы исходной последовательности, и неожиданно, что оператор "next (a)" печатает, представляется, что оператор "print i" печатает все значения.

В этом свете становится яснее, что назначение результата "next (a)" переменной запрещает печать его результата, так что печатаются только переменные значения, которые переменная цикла "i". Точно так же, если утверждение "print" испускает что-то более своеобразное, оно также может быть неоднозначно.

(Один из существующих ответов опровергает остальные, потому что этот ответ имеет пример кода, оцененный как блок, так что интерпретатор не сообщает промежуточные значения для "next (a)".)

Увлекательная вещь в ответе на вопросы, в общем, явствует о том, что очевидно, когда вы знаете ответ. Это может быть неуловимо. Точно так же критикуйте ответы, как только вы их поймете. Это интересно...

Ответ 4

Что-то не так с вашим Python/Computer.

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

>>> 
0
2
4
6
8

Работает, как и ожидалось.

Протестировано в Python 2.7 и в Python 3+. Правильно работает как в

Ответ 5

Он ведет себя так, как вы хотите, если вызывается как функция:

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