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

Andrew Barnert abarnert at yahoo.com
Thu Oct 1 08:24:24 CEST 2015


On Sep 30, 2015, at 22:39, Akira Li <4kir4.1i at gmail.com> wrote:
> 
> Andrew Barnert via Python-ideas
> <python-ideas at python.org> writes:
> 
>>> On Sep 30, 2015, at 19:04, Akira Li <4kir4.1i at gmail.com> wrote:
>>> 
>>> Random832 <random832 at fastmail.com> writes:
>>> 
>>>> Akira Li <4kir4.1i at gmail.com> writes:
>>>> 
>>>>> Andrew Barnert via Python-ideas
>>>>> <python-ideas at python.org> writes:
>>>>> ...
>>>>>> (The fact that we don't have a term for "non-iterator iterable", and
>>>>> 
>>>>> All iterators are iterable but some iterables are not iterators.
>>>>> 
>>>>> If your code accepts only iterators then use the term *iterator*.
>>>>> Otherwise the term *iterable* could be used.
>>>>> 
>>>>> It is misleading to use *iterable* if your code only accepts iterators.
>>>>> 
>>>>> If an iterable is an iterator; It is called *iterator*. The term
>>>>> *iterable* implies that some instances are not iterators.
>>>> 
>>>> There are three (well, three and a half) kinds of code that consume
>>>> iterables, how would you describe each simply?
>>>> 
>>>> 1. Does not call iter, simply calls next. Therefore cannot consume a
>>>>  non-iterator iterable.
>>> iterator
>>> 
>>>> 2. Calls iter, but can accept an iterator (e.g. only goes through it
>>>>  once)
>>> iterable
>>> 
>>>> 3. Cannot accept an iterator (goes through it twice, or permanently
>>>>  stores a reference to it, etc)
>>> neither
>>> 
>>> *iterable* is an object that you can pass to iter() to get *iterator*.
>>> An iterable does not guarantee that it yields the same items twice.
>> 
>> And this is exactly the problem. We don't have any way to simply
>> describe this thing. Hence all the confusion in this thread, and in
>> similar discussions elsewhere, and even in the docs (e.g., describing
>> dict views as sequences and then going on to explain that they're not
>> actually sequences).
> 
> Use *iterable* instead of "non-iterator iterable" -- it is that simple.

No it isn't. The word "iterable" just means "iterable". When you want to talk about sequences—a subtype of iterables—you don't just say "iterable", you say "sequence". And likewise, when you want to talk about iterables that aren't iterators, or iterables that are repeatable, or any other subtype of iterables, you have to use a word (or phrase) that actually means what you're saying.

I don't know how to explain this any better. Everyone else seems to get it, but you just post the same reply to each of them that you posted to me when they try to explain further. What am I not getting across here?

> "dict views" seems a pretty good term for dict views.
> Are you suggesting to call dict views "non-iterator iterable"?

Why would you think that?

> I don't see that it says more than that all dict views are iterable.
> 
> It seems there is a bug in the glossary: the entry name should be "dict
> views", not just "view" that is too generic for the description.

There's a much larger problem. The glossary says that dict views are sequences. They aren't. The actual documentation for dict views is a little better, because it explains that they're not actually sequences. But the problem is still there: what the docs are trying to say is that dict views are some kind of non-iterator iterable, but, because we don't have a term form that, they use the incorrect term "sequence".

> I've submitted a patch http://bugs.python.org/issue25286
> 
>> The fact that it took your previous message four paragraphs without
>> inventing a new term, to say what I said in one sentence with a new
>> term, demonstrates the problem. As does the fact that my attempted new
>> term, "non-iterator iterable", is sufficiently ugly and not
>> intuitively helpful enough that you felt the need to expand on it for
>> four paragraphs.
> 
> I don't need 4 paragraphs to describe it:
> 
>  if you need an iterator; use the term *iterator* --
>  otherwise use *iterable* unless you need something more specific e.g.,
>  *seq* name is common for generic sequences

Why would you use "seq" instead of "sequence" for the name of the abstract sequence type?

And, more importantly, what name do you use when you need something more specific than "iterable", but less specific than "sequence"—as in the glossary entry for dict views, for example?

> I don't remember ever using "non-iterator iterable".

Why would you expect to remember using it, when you're replying to a message where I invented it for lack of an established better name (and in hopes that someone would come up with one)?

> "non-iterator
> iterable" does not qualify as more specific. You need to introduce new
> requirements to the type for that.

There are things that are iterables, that are not non-iterator iterables, but the reverse is not true. It's a name for a strict subset. Which means it's more specific.

As for a new requirement: an iterable is a non-iterator iterable if its __iter__ method does not return self.

(If you're going to argue that this requirement can't be checked by, e.g., a structural type checker, remember that neither is the distinction between sequence and mapping, and that doesn't mean they're the same type.)


More information about the Python-ideas mailing list