检测python中的有序可重用项(序列)

检测python中的有序可重用项(序列),python,Python,我试图构建一个函数,它接受一个iterable并返回一个元组,前提是iterable总是以规范的方式进行迭代。例如,如果输入iterable是list或tuple-like,我想接受输入,但如果它是dict-like,我就不想接受(在键的顺序没有保证的情况下)。是否有任何python函数可以检测始终以相同顺序迭代的对象与顺序可以在不同版本之间更改或依赖于pythonhasheed的对象之间的差异 isinstance(x,collections.Sequence)实现了我想要的大部分功能,但生成

我试图构建一个函数,它接受一个iterable并返回一个元组,前提是iterable总是以规范的方式进行迭代。例如,如果输入iterable是
list
tuple
-like,我想接受输入,但如果它是
dict
-like,我就不想接受(在键的顺序没有保证的情况下)。是否有任何python函数可以检测始终以相同顺序迭代的对象与顺序可以在不同版本之间更改或依赖于
pythonhasheed
的对象之间的差异

isinstance(x,collections.Sequence)
实现了我想要的大部分功能,但生成器不是序列。下面的代码似乎是我想要的,但我不确定我是否遗漏了什么,或者是否有更通用的方法来捕获有序但不一定是可索引的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")

没有这样的功能。即使有发电机,你也希望能够捕捉到

(x for x in {1, 2, 3})
但允许

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

如果
类型(x)是dict
,我建议只发出警告。因为OrderedDistics是已订购的,所以即使
isinstance(x,dict)

您可能需要检查是否定义了切片操作:

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

这排除了字典、生成器,但欢迎字符串、元组、列表……

您还必须删除
set
和其他
dict
子类。我宁愿剪切从
collections.Set
collections.Mapping继承的任何内容,除非它也继承自
collections.OrderedDict
。当然,正如您已经很好地指出的,不可能得到这个完美的结果。@Padraickunningham:也许您的子类是有序的!即使您使用的是特例
collections.OrderedDict
,也可能您使用的是Django的旧版本,或者来自的
sortedict
。我想
在(dict,set,frozenset)中键入(x)
的警告应该是一个不错的扩展。我没有否决,但我不认为这真的比
isinstance(x,collections.Sequence)
更好,后者因为不支持生成器而被OP拒绝了。嗯。。。它测试行为而不是继承。例如,numpy.ndarray的“序列”测试失败,切片成功。要玩devils advocate,您只需测试对象是否具有接受切片的
\uuuu getitem\uuuuuu
。您没有测试它是否以任何有意义的方式订购。FWIW,
isinstance(x,collections.SomeABC)
也只是测试某些方法的存在性。。。实际上,你的方法调用了这些方法,所以这在这方面稍微好一点,但实际上并不是很多…关于生成器-你不能以相同的方式第二次遍历同一个生成器-那么为什么要包含它呢?@AdamSosnowski如果这是个问题,我想我可以使用
itertools.tee()
首先克隆生成器,但是对于我的使用,如果我破坏了原始输入,这并不重要。