Разница между итератором и объектом-перечислителем - PullRequest
0 голосов
/ 11 апреля 2020

Функция enumerate() принимает итератор и возвращает объект перечислителя. Этот объект можно рассматривать как итератор, и на каждой итерации он возвращает 2-кортеж с первым элементом кортежа - номер итерации (по умолчанию начинается с 0), а вторым элементом - следующий элемент из итератора enumerate() на.

Как указано в "Программирование на Python 3 Полное введение в язык Python.

Я новичок в Python и не совсем понимаю, что это означает из вышеприведенного текста. Однако, исходя из моего понимания из примера кода, объект перечислителя возвращает кортеж с номером индекса и значением итератора. Прав ли я?

В чем разница между итератор и перечислитель?

1 Ответ

1 голос
/ 11 апреля 2020

Ваше понимание того, что оно в конечном итоге делает, является правильным, но формулировка в этой цитате вводит в заблуждение. Нет никакой разницы между «перечислителем» (на самом деле не стандартным термином) и итератором, или, скорее, «перечислителем» является итератор типа . enumerate возвращает объект enumerate, поэтому enumerate равен классу :

>>> enumerate
<class 'enumerate'>
>>> type(enumerate)
<class 'type'>
>>> enumerate(())
<enumerate object at 0x10ad9c300>

Как и другие встроенные типы list:

>>> list
<class 'list'>
>>> type(list)
<class 'type'>
>>> type([1,2,3]) is list
True

Или пользовательские типы:

>>> class Foo:
...     pass
...
>>> Foo
<class '__main__.Foo'>
<class 'type'>
>>> type(Foo())
<class '__main__.Foo'>
>>>

enumerate объекты являются итераторами . Дело не в том, что они могут быть «обработаны как » итераторы, они являются итераторами , итераторы - это любые типы, которые удовлетворяют следующим критериям: они определяют __iter__ и __next__:

>>> en = enumerate([1])
>>> en.__iter__
<method-wrapper '__iter__' of enumerate object at 0x10ad9c440>
>>> en.__next__
<method-wrapper '__next__' of enumerate object at 0x10ad9c440>

И iter(iterator) is iterator:

>>> iter(en) is en
True
>>> en
<enumerate object at 0x10ad9c440>
>>> iter(en)
<enumerate object at 0x10ad9c440>

См .:

>>> next(en)
(0, 1)

Теперь, чтобы указать c, он не возвращает индекс значение per se , вернее, он возвращает двукратный кортеж, содержащий следующее значение в передаваемой итерации и монотонно увеличивающиеся целые числа, по умолчанию начинающиеся с 0, но он может принимать параметр start и передаваемая итерация не должна быть индексируемой:

>>> class Iterable:
...     def __iter__(self):
...         yield 1
...         yield 2
...         yield 3
...
>>> iterable = Iterable()
>>> iterable[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Iterable' object is not subscriptable
>>> list(enumerate(iterable))
[(0, 1), (1, 2), (2, 3)]
>>> list(enumerate(iterable, start=1))
[(1, 1), (2, 2), (3, 3)]
>>> list(enumerate(iterable, start=17))
[(17, 1), (18, 2), (19, 3)]
...