XQ_CHIA
XQ_CHIA

Reputation: 168

Difference between Iterator and Enumerator object

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 iterator enumerate() 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

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

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

Related Questions