# Is there a canonical way to check whether an iterable is ordered?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Sep 19 07:15:16 CEST 2014

```Roy Smith wrote:

> Is there anything which requires an iterator to be deterministic?

Absolutely not.

py> def spam():
...     while True:
...         n = random.randint(0, 10)
...         s = ' '.join(['spam']*n)
...         if not s:
...             return
...         yield s + '!'
...
py> for s in spam():
...     print(s)
...
spam spam spam spam spam spam!
spam spam!
spam spam spam spam spam spam spam spam spam!
spam spam spam spam spam spam spam!
py>

> For
> example, let's say I have an iterable, i, and I do:
>
> list1 = [item for item in i]
> list2 = [item for item in i]

Don't do that. Just write:

list1 = list(i)
list2 = list(i)

> am I guaranteed that list1 == list2?

No.

However, as far as I am aware, there are no built-ins that will fail that
test, yet. Although the iteration order of dicts and sets is arbitrary, I
think that (at least to date) it will be the same order every time you
iterate over the dict or set within a single run of the Python interpreter.
(Provided the dict or set hasn't changed.)

That's not a language guarantee though. It's an implementation detail. In
principle, it could be different each time:

s = set("abcd")
list(s)
=> returns ['d', 'a', 'b', 'c']
list(s)
=> returns ['c', 'a', 'd', 'b']

> It will be for all the collections
> I can think of in the standard library, but if I wrote my own class with
> an __iter__() which yielded the items in a non-deterministic order,
> would I be violating something other than the principle of least
> astonishment?

Nope.

--
Steven

```