在Python中,如何确定迭代是否具有稳定的迭代顺序?
有collections.Iterable
抽象基类,但没有稳定的对应物。
我问的原因是当他们(通过错误)通过不稳定的迭代顺序(dict
,set
等)迭代到函数时能够阻止用户或警告他们迭代的稳定性至关重要。
答案 0 :(得分:5)
您可能正在寻找的一件事是collections.Sequence
。这比你想要的更具体,因为根据the docs,序列“支持使用整数索引的有效元素访问”;它也不够具体,因为没有明确保证两次获得相同的索引必须两次都返回相同的值。但这足以将列表和元组与dicts和sets区分开来。
然而,总的来说没有办法。一般来说,没有办法,因为你可以编写你喜欢的任何迭代,并且不要求你指定它是否稳定。例如,你可以这样做:
>>> def f():
... if random.random() < 0.5:
... for a in xrange(10):
... yield a
... else:
... stuff = range(10)
... random.shuffle(stuff)
... for a in stuff:
... yield a
>>> list(f())
0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(f())
1: [7, 0, 2, 8, 5, 1, 4, 3, 6, 9]
迭代器可以在不必声明它们是否稳定的情况下编写,而且事实上没有办法通过迭代判断它是否会以相同的方式迭代,这意味着那里无法判断给定的迭代器是否稳定。
我建议您简单地记录您的函数需要迭代顺序的稳定性。您还可以显式检查您知道可能不稳定的内置类型,并在这些类型上引发错误。但是没有办法检查任意用户定义的迭代器稳定性的稳定性。