2016-10-29 3 views
-2

Что касается итераторов и итерируемых (мое наблюдение только и, пожалуйста, поправьте меня, если я ошибаюсь):методы, которые берут итераторы вместо итерируемых

  • Большинства конструкторов (из arrayish-типов) принимают итераторы как массы-конструктор
  • итераторы явно сделаны; или с помощью x in x for....
  • Многих метод (в основном, itertools) возвращает итератор (потому что их работа заключается в итерации?)
  • Методы, которые принимают итерируемые принимать итераторы. Действительно ли это во всех случаях?
  • Методы, которые берут итераторы не будет принимать итерируемых (не наоборот)
  • Единственный метод, который явно принимает итератор, кажется next(..

Вопросы:

  • Are есть ли другие методы, которые принимают итераторы?

  • Каковы другие способы создания итераторов с синтаксисом? например: x in x for...

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

ответ

1

Язык вокруг итераторов и итераций немного запутан. Основная путаница исходит из термина «итерируемый», который может быть или не быть надмножеством «итератора», в зависимости от того, как он используется.

Вот как я бы классифицировать вещи:

итерацию является любой объект, который может повторяться на. То есть он имеет метод __iter__(), который возвращает итератор, или он индексируется с целыми числами (повышение исключения IndexError, когда они находятся за пределами допустимого диапазона), что позволяет Python автоматически создавать итератор для него. Это очень широкая категория.

Итератор - объект, который следует за протоколом итератора. Он имеет метод __next__() (пишется next в Python 2), который дает следующий элемент или вызывает исключение StopIteration, если больше нет доступных значений. Итератор также должен иметь метод __iter__(), который возвращает себя, поэтому все итераторы также являются итерабельными (поскольку они соответствуют определению «итерируемое», приведенному выше).

не-итератора итератора является любой итерацию, что является не итератора. Это часто означает люди, когда они используют термин «итерируемый» в отличие от «итератора». Лучшим термином во многих контекстах может быть «последовательность», но это немного более конкретный (некоторые объекты без последовательности являются итераторами без итератора, такими как словари, которые позволяют итерации по их ключам). Важной особенностью этой категории объектов является то, что вы можете повторять их несколько раз, и итераторы работают независимо друг от друга.

Так, чтобы попытаться ответить на ваши конкретные вопросы:

Там редко хорошая причина для любой функции требует итератора специально. Функции обычно можно выполнять так же хорошо, как и любой итеративный аргумент, либо путем вызова iter() аргумента для получения итератора, либо с помощью цикла for, который создает итератор за кулисами.

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

Многие функции возвращают итераторы. Все объекты генератора являются, например, итераторами (как те, которые возвращаются функциями генератора, так и те, которые созданы с помощью выражений генератора). Файловые объекты также являются итераторами (хотя они немного нарушают протокол итератора, так как вы можете перезапустить их после того, как они исчерпаны, используя их метод seek()). И все функции и типы в модуле itertools возвращают итераторы, но так делают некоторые встроенные функции, такие как map() (в Python 3).

Функция next() действительно необычна, поскольку для этого требуется итератор. Это связано с тем, что он определяется как часть самого итерационного протокола. Это точно эквивалентно вызову метода __next__() на итераторе, который лучше читать. Он также имеет форму с двумя аргументами, которая подавляет исключение StopIteration, которое в противном случае было бы поднято, если итератор исчерпан (вместо этого он возвращает аргумент default).

+0

Благодарим вас за подробное объяснение. Чтобы уточнить, list/tuple/range - это тип последовательности. Не регулярный итеративный, но неитератор итеративный. 'next (..' принимает итератор, который также является итерабельным.Но он отличается от другого типа итерабельного (non-iterator iterable) = sequence = list/tuple/range. (Конкретные подробности других различий приведены в ваших комментариях) Есть больше из них, итерабельны, с обобщением: с __iter __()? – theMobDog

+1

Да, я думаю, что у вас это есть. Итерабель - это самый общий термин. Некоторые итераторы - итераторы, другие - нет. Я называю те, не являются «итераторными итераторами», но многие просто называют их «итерабельными», приводящими к путанице (поскольку неясно, имеют ли они более общий термин или более конкретную неитераторную подкатегорию). – Blckknght

Смежные вопросы