Your understanding of what it ultimately does is correct, but the phrasing in that quote is misleading. There is no difference between an "enumerator" (not really a standard term) and an iterator, or rather, the "enumerator" is a kind of iterator. enumerate
returns an enumerate
object, so enumerate
is a class:
>>> enumerate
<class 'enumerate'>
>>> type(enumerate)
<class 'type'>
>>> enumerate(())
<enumerate object at 0x10ad9c300>
Just like other built-in types list
:
>>> list
<class 'list'>
>>> type(list)
<class 'type'>
>>> type([1,2,3]) is list
True
Or custom types:
>>> class Foo:
... pass
...
>>> Foo
<class '__main__.Foo'>
<class 'type'>
>>> type(Foo())
<class '__main__.Foo'>
>>>
enumerate
objects are iterators. It is not that they can be "treated like" iterators, they are iterators, Iterators are any types that fulfill the following criteria: they define a __iter__
and __next__
:
>>> en = enumerate([1])
>>> en.__iter__
<method-wrapper '__iter__' of enumerate object at 0x10ad9c440>
>>> en.__next__
<method-wrapper '__next__' of enumerate object at 0x10ad9c440>
And iter(iterator) is iterator
:
>>> iter(en) is en
True
>>> en
<enumerate object at 0x10ad9c440>
>>> iter(en)
<enumerate object at 0x10ad9c440>
See:
>>> next(en)
(0, 1)
Now, to be specific, it doesn't return an index value per se, rather, it returns a two-tuple containing the next value in the iterable passed in along with monotonically increasing integers, by default starting at 0
, but it can take a start
parameter, and the iterable passed in doesn't have to be indexable:
>>> 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)]