5

したがって、Python 2では、次のようなものを使用できます

>>> items = [[1, 2], [3], [3], 4, 'a', 'b', 'a']
>>> from itertools import groupby
>>> [k for k, g in groupby(sorted(items))]
[4, [1, 2], [3], 'a', 'b']

これは時間内にうまく機能しO(N log N)ます。ただし、Python 3 ではTypeError: unorderable types: int() < list(). では、Python 3でそれを行う最良の方法は何ですか? (私は主観的な用語であることを最もよく知っていますが、実際にはPythonに従ってそれを行う方法が1つあるはずです)

編集:ソートを使用する必要はありませんが、それが最善の方法だと思います

4

2 に答える 2

6

2.x では、比較できない 2 つの組み込み型の値が型別に並べられています。型の順序は定義されていませんが、インタープリターの 1 回の実行中は一貫しています。したがって、2 < [2]真または偽の可能性がありますが、一貫して真または偽になります。

3.x では、比較できない組み込み型の値は比較できません。つまり、それらTypeErrorを比較しようとすると、 a が発生します。だから、2 < [2]エラーです。そして、少なくとも 3.3 の時点では、型自体は比較できません。しかし、再現したいのが 2.x の動作だけであればid、インタープリターの実行中、それらの s は間違いなく比較可能であり、一貫性があります。そう:

sorted(items, key=lambda x: (id(type(x)), x))

あなたのユースケースでは、これで十分です。


ただし、これは 2.x とまったく同じではありません。たとえば、(because > ) で1.5 < 2ある可能性があるためです。正確な動作を再現したい場合は、最初に値を比較しようとし、次にフォールバックして型を比較す​​るキー関数を作成する必要があります。FalsefloatintTypeError

これは、新しいスタイルの関数cmpよりも古いスタイルの関数の方がはるかに読みやすい数少ないケースの 1 つです。keycmp_to_key

def cmp2x(a, b):
    try:
        if a==b: return 0
        elif a<b: return -1
        elif b<a: return 1
    except TypeError:
        pass
    return cmp2x(id(type(a)), id(type(b)))
sorted(items, key=functools.cmp_to_key(cmp2x))

これは、2.x が与える異なる型の 2 つの値の間で同じ順序を保証するものではありませんが、2.x はそのような順序を定義していないため (1 回の実行内で一貫しているだけです)、それができる方法はありません。

ただし、まだ 1 つの実際の欠陥があります。オブジェクトが完全に順序付けされていないクラスを定義すると、それらは最終的に同じものとしてソートされます。これが 2.x がその場合に行うのと同じことかどうかはわかりません。

于 2013-04-15T11:51:01.357 に答える