[Python-ideas] Consider making enumerate a sequence if its argument is a sequence

M.-A. Lemburg mal at egenix.com
Wed Sep 30 21:47:17 CEST 2015

On 30.09.2015 21:19, Andrew Barnert wrote:
> On Sep 30, 2015, at 11:43, M.-A. Lemburg <mal at egenix.com> wrote:
>>> On 30.09.2015 20:26, Andrew Barnert via Python-ideas wrote:
>>>> On Sep 30, 2015, at 11:11, M.-A. Lemburg <mal at egenix.com> wrote:
>>>>> On 30.09.2015 19:19, Neil Girdhar wrote:
>>>>> I guess, I'm just asking for enumerate to go through the same change that
>>>>> range went through.  Why wasn't it a problem for range?
>>>> range() returns a list in Python 2 and a generator in Python 3.
>>> No it doesn't. It returns a (lazy) sequence. Not a generator, or any other kind of iterator.
>> You are right that it's not of a generator type
>> and more like a lazy sequence. To be exact, it returns
>> a range object and does implement the iter protocol via
>> a range_iterator object.
> To be exact, it returns an object which returns True for isinstance(r, Sequence), which offers correct implementations of the entire sequence protocol. In other words, it's not "more like a lazy sequence", it's _exactly_ a lazy sequence.
> In 2.3-2.5, xrange was a lazy "sequence-like object", and the docs explained how it didn't have all the methods of a sequence but otherwise was like one. When the collections ABCs were added, xrange (2.x)/range (3.x) started claiming to be a sequence, but the implementation was incomplete, so it was defective. This was fixed in 3.2 (which also made all of the sequence methods efficient—e.g., a range that fits into C longs can test an int for __contains__ in constant time).
>>> I don't know why so many people seem to believe it returns a generator. (And, when you point out what it returns, most of them say, "Why was that changed from 2.x xrange, which returned a generator?" but xrange never returned a generator either--it returned a lazy almost-a-sequence from the start.)
>> Perhaps because it behaves like one ? :-)
>> Unlike an iterator, it doesn't iterate over a sequence, but instead
>> generates the values on the fly.
> You're confusing things even worse here.

I guess I used the wrong level of detail. I was trying
explain things in terms of concepts, not object types,
isinstance() and ABCs.

The reason was that the subject line makes a suggestion
which simply doesn't fit the main concept behind enumerate:
that of generating values on the fly instead of allocating
them as sequence.

We just got side tracked with range(), since Neil brought
this up as example of why changing enumerate() should be

Back on the topic:

>>> arg = range(10)
>>> e = enumerate(arg)
>>> e
<enumerate object at 0x7fcbbc57bd80>
>>> import collections
>>> isinstance(e, collections.Sequence)
>>> isinstance(e, collections.Iterator)

The way I understand the proposal is that Neil wants the
above to return:

>>> isinstance(e, collections.Sequence)
>>> isinstance(e, collections.Iterator)

iff isinstance(arg, collections.Sequence)

and because this only makes sense iff e doesn't actually
create a list, enumerate(arg) would have to return a
sequence :-)

Regardless of this breaking backwards compatibility,
what's the benefit of such a change ?

Just like range(), enumerate() is most commonly used
in for-loops, so the added sequence-ishness doesn't buy
you anything much (except the need for more words in
the glossary :-)).

Marc-Andre Lemburg

Professional Python Services directly from the Experts (#1, Sep 30 2015)
>>> Python Projects, Coaching and Consulting ...  http://www.egenix.com/
>>> Python Database Interfaces ...           http://products.egenix.com/
>>> Plone/Zope Database Interfaces ...           http://zope.egenix.com/
2015-09-25: Started a Python blog ... ...          http://malemburg.com/
2015-10-21: Python Meeting Duesseldorf ...                 21 days to go

::::: Try our mxODBC.Connect Python Database Interface for free ! ::::::

   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611

More information about the Python-ideas mailing list