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

4 に答える 4

4

コレクションが真に恣意的なものである場合 (つまり、どのクラスでもかまいません)、答えは no でなければなりません

基本的に、次の 2 つの方法があります。

  1. メソッドに提示できる可能性のあるすべてのクラスと、それが順序付けられているかどうかを把握します。
  2. 考えられるすべてのキーの組み合わせをコレクションに挿入し、順序が維持されるかどうかを確認して、コレクションを自分でテストします。

後者は明らかに不可能です。前者は、 ;などのすべての派生クラスについて知っておく必要があることを除いて、既に持っているものと同じです。collections.OrderedDictをチェックするだけでは十分でdictはありません。

率直に言って、is_ordered小切手全体はワームの缶詰だと思います。とにかく、なぜこれをやりたいのですか?

于 2012-05-02T10:39:04.470 に答える
1

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

静的に型付けされた言語では、特定の型に自分自身を制限するだけです。本当にそれを複製したい場合は、受け入れるタイプのみを指定し、それらをテストしてください。他のものが渡された場合は、例外を発生させます。Pythonicではありませんが、やりたいことを確実に実現します


さて、あなたには2つの可能なアプローチがあります:

  1. メソッドを持つものはすべて、appendほぼ確実に順序付けされます。と
  2. メソッドしかない場合はadd、ナンス値を追加してから、コレクションを繰り返し処理して、ナンスが最後 (または、おそらく一方の端) に表示されるかどうかを確認できます。2 番目の nonce を追加して、もう一度やり直して、自信を持たせることができます。

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

おそらくより良い解決策は、コードが順序付けられたコレクションを必要とすることを指定し、順序付けられたコレクションのみを渡すことです。

于 2012-05-02T10:50:14.920 に答える
0

90% のケースを列挙することは、得られるものとほぼ同じだと思います (Python 3 を使用している場合は、basestring を str に置き換えます)。おそらく、ジェネレーター式や同様の同類をどのように処理するかについても検討する必要があります (Py3 を使用している場合は、xrangor をスキップしてください)。

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))

呼び出し元が itertools の使用を開始した場合は、islice、imap、groupby によって返される itertools タイプも追加する必要があります。しかし、これらの特殊なケースの膨大な数は、実際にはコードの匂いを示し始めています。

于 2012-05-02T13:26:53.480 に答える
-1

[1,3,2] のように、リストが順序付けされていない場合はどうなるでしょうか。

于 2012-05-02T10:39:47.053 に答える