Reputation: 168
The
enumerate()
function takes an iterator and returns an enumerator object. This object can be treated like an iterator, and at each iteration it returns a 2-tuple with the tuple's first item the iteration number (by default starting from 0), and the second item the next item from the iteratorenumerate()
was called on.
As quoted from "Programming in Python 3 A Complete Introduction to the Python Language.
I'm new to Python and don't really understand what it means from the text above. However, from my understanding from the example code, enumerator object returns a 2-tuple with the index number and the value of the iterator. Am i right?
What is the difference between iterator and enumerator?
Upvotes: 3
Views: 4080
Reputation: 95957
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)]
Upvotes: 4