2016-06-28 15 views
2

iterableを常に標準的な方法で反復処理するという条件で、iterableを受け取り、tupleを返す関数を作成しようとしています。たとえば、入力の繰り返しがlistまたはtupleのような場合は、入力を受け入れますが、dictのようなものではありません(キーの順番での保証はありません)。同じ順序で反復されるオブジェクトと、バージョン間のバージョンが変更される可能性があるオブジェクト、またはPYTHONHASHSEEDに依存するオブジェクトの間で、異なるオブジェクトを検出するPython関数はありますか?Pythonで順序付きiterables(シーケンス)を検出する

isinstance(x, collections.Sequence)私が望むほとんどのものは行いますが、ジェネレータはシーケンスではありません。次のコードは私が望むことをしているようですが、何かを残しているのか、順序付けられたアイデアをキャプチャするより一般的な方法があるかどうかはわかりません。

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") 
+1

- あなたが行くことができません同様の方法で同じ発電機で2回目です。なぜそれを含めるのですか? –

+0

@AdamSosnowskiそれが問題であれば、私は 'itertools.tee()'を使ってジェネレータを最初にクローン化することができますが、私の用途では、元の入力をマングリングしても問題ありません。 –

答えて

2

このような機能はありません。でも発電機で、あなたは

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

をキャッチできるようにしたいが、

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

を許可したい私はtype(x) is dict場合は単なる警告を上げることをお勧めしたいです。 OrderedDictsが注文されているので、isinstance(x, dict)もありません。スライス操作が定義されている場合

+1

また、 'set'や他の' dict'サブクラスを削除する必要があります。 Collections.OrderedDictから継承しない限り、 'collections.Set'や' collections.Mapping'を継承するものは除外したいと思います。もちろん、あなたが非常によく指摘しているように、これを完璧にすることは不可能です。 – mgilson

+0

@PadraicCunningham:あなたのサブクラスが注文されているかもしれません!特殊ケースの 'collections.OrderedDict'を使用していても、Djangoの古い[' SortedDict'](https://code.djangoproject.com/wiki/SortedDict)や[SortedContainers]の 'SortedDict'( https://pypi.python.org/pypi/sortedcontainers)。私は 'type(x)in(dict、set、frozenset)の警告は大丈夫だと思います。 – user2357112

0

かを確認することもできます。

辞書、発電機を除外、しかし、文字列、タプル、リストを歓迎
def to_tuple(x): 
    return tuple(x[:]) 

...発電機について

+0

そしてdownvote - なぜ? –

+1

私はdownvoteをしませんでしたが、これは実際にはOPがジェネレータをサポートしていないために拒否したisinstance(x、collections.Sequence)よりも優れているとは思えません。 – mgilson

+0

これは、継承の代わりに動作をテストします。たとえば、numpy.ndarrayの "Sequence"テストが失敗し、スライスが成功します。 –

関連する問題