[Python-ideas] Indicate if an iterable is ordered or not
Terry Reedy
tjreedy at udel.edu
Tue Sep 24 23:16:40 CEST 2013
On 9/24/2013 12:15 PM, Eric Snow wrote:
> Iterables are not necessarily ordered (e.g. dict vs. OrderedDict).
> Sequences are but Sets aren't. I'm not aware of any good way
> currently to know if an arbitrary iterable is ordered. Without an
> explicit indicator of ordered-ness, you must know in advance for each
> specific type.
>
> One possible solution is an __isordered__ attribute (on the class),
> set to a boolean. The absence of the attribute would imply False.
>
> Such an attribute would be added to existing types:
>
> * collections.abc.Iterable (default: False)
> * list (True)
> * tuple (True)
> * set (False)
> * dict (False)
> * collections.OrderedDict (True)
> * ...
>
> Thoughts?
The iterator protocol is intentionally simple. It only requires an
__iter__ method or a __next__ method with a standard __iter__ method.
This makes iterables -- and generator functions that produce iterators
-- easy to write.
A generator instance may and may not produce items in an intented order,
so a class attribute is not possible. The same is generally true of
transform iterators, like map and filter instances, and most itertools
classes. It is also not true that lists (and tuples) always have a
significant order. list(set) has the artificial order of set iteration.
Both are reiterable with the same order. Why would you call one True
and the other False? In general, list(iterable) has as much order as the
iterable.
The __isordered__ attribute would have to be an instance attribute,
properly propagated. How would you do that with generator functions? or
generator expression?
Anyone is free to privately extend the protocol for special purposes and
restrict their universe to object that follow. Builtins can be extended,
wrapped, or mapped, or their internal iterator classes mapped, to make
them conform. The following helps with the last idea.
>>> for cls in list, tuple, set, frozenset, dict:
type(iter(cls()))
<class 'list_iterator'>
<class 'tuple_iterator'>
<class 'set_iterator'>
<class 'set_iterator'>
<class 'dict_keyiterator'>
--
Terry Jan Reedy
More information about the Python-ideas
mailing list