Python では、イテラブルの反復順序が安定しているかどうかを判断するにはどうすればよいですか?
collections.Iterable
抽象基本クラスはありますが、対応する安定したクラスはありません。
私が尋ねている理由は、反復の安定性が重要な関数に不安定な反復順序 ( dict
、など) で (誤って) iterable を渡したときに、ユーザーを防止したり、警告したりできるようにするためです。set
Python では、イテラブルの反復順序が安定しているかどうかを判断するにはどうすればよいですか?
collections.Iterable
抽象基本クラスはありますが、対応する安定したクラスはありません。
私が尋ねている理由は、反復の安定性が重要な関数に不安定な反復順序 ( dict
、など) で (誤って) iterable を渡したときに、ユーザーを防止したり、警告したりできるようにするためです。set
あなたが探しているかもしれないことの1つはcollections.Sequence
. ドキュメントによると、シーケンスは「整数インデックスを使用した効率的な要素アクセスをサポートする」ため、これは必要なものよりも少し具体的です。また、同じインデックスを 2 回取得すると同じ値が返されることを明示的に保証するものは何もないため、十分に具体的ではありません。しかし、リストとタプルを dict とセットから区別するにはこれで十分でしょう。
ただし、一般的には方法がありません。一般に、好きなイテラブルを書くことができ、それが安定しているかどうかを指定する必要がないため、方法はありません。たとえば、次のようなことができます。
>>> 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]
イテレータは、安定しているかどうかを宣言する必要なく記述できるという事実と、後で同じように反復するかどうかを反復することによって判断する方法がないという事実は、何もないことを意味します。指定されたイテレータが安定しているかどうかを判断する方法。
関数には繰り返し順序の安定性が必要であることを簡単に文書化することをお勧めします。また、安定していない可能性があることがわかっている組み込み型を明示的にチェックし、それらに対してエラーを発生させることもできます。しかし、一般に、任意のユーザー定義イテレーターの安定性をチェックする方法はありません。