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
ある可能性があるためです。正確な動作を再現したい場合は、最初に値を比較しようとし、次にフォールバックして型を比較するキー関数を作成する必要があります。False
float
int
TypeError
これは、新しいスタイルの関数cmp
よりも古いスタイルの関数の方がはるかに読みやすい数少ないケースの 1 つです。key
cmp_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 がその場合に行うのと同じことかどうかはわかりません。