Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting ordered iterables (sequences) in python

Tags:

python

I am attempting to build a function that takes an iterable and returns a tuple, provided that the iterable will always be iterated over in a canonical way. For example, if the input iterable is list or tuple-like, I want to accept the input, but not if it is dict-like (where there isn't a guarantee on the order of the keys). Is there any python function to detect the different between objects that are always iterated in the same order vs. those where the order could change version-to-version or depend on PYTHONHASHSEED?

isinstance(x, collections.Sequence) does most of what I want, but generators are not sequences. The following code seems to do what I want, but I'm not sure if I'm leaving something out or if there is a more general way to capture the idea of an ordered, but not necessarily indexable, iterable.

import collections, types
def to_tuple(x):
    if isinstance(x, collections.Sequence) or isinstance(x, types.GeneratorType):
        return tuple(x)
    raise Exception("Cannot be iterated canonically")
like image 822
Jason Siefken Avatar asked Sep 02 '25 01:09

Jason Siefken


2 Answers

There's no such function. Even with generators, you'd want to be able to catch

(x for x in {1, 2, 3})

but permit

(x for x in [1, 2, 3])

I'd recommend just raising a warning if type(x) is dict. Not even isinstance(x, dict), because OrderedDicts are ordered.

like image 60
user2357112 supports Monica Avatar answered Sep 04 '25 16:09

user2357112 supports Monica


You may want to check if slicing operation is defined:

def to_tuple(x):
  return tuple(x[:])

That rules out dictionaries, generators, but welcomes strings, tuples, lists...

like image 39
Adam Sosnowski Avatar answered Sep 04 '25 16:09

Adam Sosnowski