2012-05-02 4 views
1

は、私がこれまで持っているものです。任意のコレクションがあれば、注文されているかどうかを判断する方法はありますか?ここ

def is_ordered(collection): 
    if isinstance(collection, set): 
     return False 
    if isinstance(collection, list): 
     return True 
    if isinstance(collection, dict): 
     return False 

    raise Exception("unknown collection") 

は、これを行うためのより良い方法はありますか?

NB:私は注文しており、ではありません。

動機:

私が注文したコレクションを反復処理します。例えば

def most_important(priorities): 
    for p in priorities: 
     print p 

この場合、優先順位が順序付けられているという事実が重要です。それはどのようなコレクションではありません。私はここでダックタイピングをしています。私はしばしばPythonistasによる型チェックから躊躇しています。

+4

あなたのコードは既に 'collections.OrderedDict'のインスタンスでは失敗します –

+0

そして私が想定している他の様々なもの。ポイントは、すべてのコレクションをテストする必要があるのか​​、それとももっと堅牢な方法があるのでしょうか? – cammil

+2

これを繰り返して、呼び出し元が順序付けされたコレクションを渡していることを確認してください。 – Marcin

答えて

4

コレクションが真に任意の場合(つまり、どのクラスでもかまいません)、回答はでなく、でなければなりません。

基本的には、2つの可能なアプローチがあります。

  1. あなたの方法に提示することができ、すべての可能なクラスを知って、それが注文したのかどうかは、
  2. 可能性のあるすべてのキーの組み合わせを挿入し、順序が保持されているかどうかを確認してコレクションをテストします。

後者は明らかに実行不可能です。前者はあなたがすでに持っているものに沿っています。ただし、はのように、クラスから派生していることを知る必要があります。 dictのチェックでは不十分です。

率直に言えば、全体のis_orderedのチェックはワームの缶です。とにかくこれをやりたいのですが?

+0

私は役に立つかもしれない標準的な制限はありますか?あるいは私がしたようにクラスチェックに頼るべきですか? – cammil

+0

@cammil人間の言語(英語など)を使用して注文したコレクションのみを渡す必要があるのはなぜですか? – Marcin

+0

編集を参照してください。それはあなたの質問に答えますか? – cammil

-1

リストが注文されていない場合はどうなりますか? [1,3,2]?

+2

[1,3,2] _is_が発注されました。ソートされていません。 – cammil

+0

「注文しました」ということは何を意味するのでしょうか?しかし、私はaixが書いたことに同意します - 本当にあなたはできません。誰でも順序付けされた "dict"を実装することができます。コレクションライブラリにはOrderedDictクラスがあります。 – uhz

+1

@uhzzre: '' hello ''のような文字列をとります。それは注文されます(=文字の順序は重要です)。それはソートされていませんが、それは '' ehllo ''です。 –

1

更新:本質的に、あなたに渡された引数をunittestしようとしています。それをやめ、あなた自身のコードをユニットテストしてください。コンシューマーをテストし(順序付けされたコレクションで動作することを確認する)、それを呼び出すコードをユニットテストし、正しい結果が得られるようにします。

静的型言語では、自分自身を特定の型に制限するだけです。本当にそれを複製したい場合は、受け入れる唯一のタイプを指定し、それらをテストします。何か他のものが渡された場合は例外を発生させます。それはニシキヘビではないのですが、それは確実にあなたが


まあやりたいものを達成し、次の2つの可能なアプローチがあります。append方法と

  1. 何かがほぼ確実に注文されると、
  2. addメソッドしかない場合は、ノンス値を追加してから、コレクションの両端を反復して、ノンスが最後に表示されているかどうかを確認することができます。第2のノンスを追加して、自信を持ってやり直すこともできます。

もちろん、これは機能しません。コレクションが空であるか、または最後に追加されない順序付け関数がある場合

おそらく、あなたのコードに順序付きコレクションが必要であることを指定し、順序付きコレクションのみを渡すことをお勧めします。

0

90%のケースを列挙することは、(Python 3を使用している場合は、basestringをstrに置き換える)と同じくらい良いと思います。おそらく、また、(再び、PY3を使用している場合、xrangorをスキップ)あなたも、ジェネレータ式と同様の同類を処理する方法を検討する必要:あなたの発信者がitertoolsを使用して起動した場合

generator = type((i for i in xrange(0))) 
enumerator = type(enumerate(range(0))) 
xrangor = type(xrange(0)) 
is_ordered = lambda seq : isinstance(seq,(tuple, list, collections.OrderedDict, 
              basestring, generator, enumerator, xrangor)) 

、その後も追加する必要がありますiteroolsは、islice、imap、groupbyによって返される型です。しかし、これらの特別なケースの真の数は、実際にはcode smellを指し始める。