[Python-ideas] Consider making enumerate a sequence if its argument is a sequence
Andrew Barnert
abarnert at yahoo.com
Thu Nov 5 04:17:24 EST 2015
On Nov 4, 2015, at 19:45, Michael Selik <mike at selik.org> wrote:
>
> On 02.10.2015 05:49, Steven D'Aprano wrote:
> > At most, some have suggested that we don't have a good
> > word for those iterables which are not iterators.
>
> Isn't that a "sequence"? The collections module defines a Sequence as having a __getitem__ and __len__. Is a "non-iterator iterable" something different?
A mapping isn't a sequence (even though it has __getitem__ and __len__, and also has the same supertypes, which add additional restrictions that you forgot like __contains__). Neither is a set, or any of the kinds of mapping views, or any intentionally-not-quite-sequence (like range before 3.2, or, IIRC, blist.sortedlist), or an iterable that, each time it's iterated, gives you 20 new values in [0, 1) that add up to 1. But they're all non-iterator iterables.
In fact, there are a number of concepts that largely overlap, but don't completely, including:
* Iterables that aren't iterators
* Iterables that don't return self from __iter__
* Iterables that always return a new iterator
* Iterables that can repeatably produce a "correct" sequence of values (as long as they aren't mutated in between iterations)
* Iterables that can repeatably produce equal values (as long as they aren't mutated)
* Iterables that can repeatedly produce identical values (as long as they aren't mutated)
There are also variations of the last three that represent some data that can be "externally mutated" (e.g., a list of all broadcasting SMB servers on the local subnet will always produce equal values unless a server goes up or down between iterations—or, more simply, any view can change values if the thing it's a view of is mutated, without the view itself being mutated).
Anyway, all of the above are true for sequences, mappings, sets, mapping views, and most not-quite-sequences, but not for the random example, or the SMB example.
I don't think we need official names for all of these things, just one—as long as it's clear which one, and exactly what it means, I think that will cover well over 90% of all reasonable uses.
I believe that earlier in the thread, Terry suggested "collection" to mean the last definition, which seems fine at first glance, so let's assume that. If we added that to the documentation (and fixed all the places that sloppily talk about sequences when they don't really mean sequences, etc.), and ideally added an ABC and a static type to match, then code could very easily explain that it produces or requires a collection. Most code that needs two passes over an iterable can just say it requires a collection. The fact that it might also work with some sort-of-repeatable-but-not-quite-collection types is fine (and we don't have to say that such types are "defective" or anything, as long as the documentation makes it clear that there are some very rare iterables that are neither iterators nor collections, and what that means).
Of course Collection defined this way can't be an implicit ABC, because it doesn't have any interface beyond that of Iterator. But then Sequence and Mapping can't be implicit either, because they have the same interface as each other. In fact, that's the main reason we need ABCs in the first place—for cases where structural/duck typing can't cover the intended semantics.
More information about the Python-ideas
mailing list