[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