On Sep 30, 2015, at 10:47, Chris Barker <chris.barker@noaa.gov> wrote:

On Wed, Sep 30, 2015 at 10:33 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
On 30.09.15 20:18, Neil Girdhar wrote:
Ah good point.  Well, in the case of a sequence argument, an enumerate
object could be both a sequence and an iterator.

It can't be.

For sequence:

>>> x = 'abcd'
>>> list(zip(x, x))
[('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd')]

For iterator:

>>> x = iter('abcd')
>>> list(zip(x, x))
[('a', 'b'), ('c', 'd')]

well, that's because zip is using the same iterator it two places. would that ever be the case with enumerate?

The point is that _nothing_ can be an iterator and a sequence at the same time. (And therefore, an enumerate object can't be both at the same time.)

The zip function is just a handy way of demonstrating the problem; it's not the actual problem. You could also demonstrate it by, e.g., calling len(x), next(x), list(x): If x is an iterator, next(x) will use up the 'a' so list will only give you ['b', 'c', 'd'], even though len gave you 4.

Conceptually: iterators are inherently one-shot iterables; sequences are inherently reusable iterables. While there's no explicit rule that __iter__ can't return self for a sequence, there's no reasonable way to make a sequence that does so. Which means no sequence can be an iterator.