35

を使用してオブジェクトのリストをソートしようとしています

my_list.sort(key=operator.attrgetter(attr_name))

ただし、リスト項目のいずれかのattr = None代わりattr = 'whatever'

それから私はTypeError: unorderable types: NoneType() < str()

Py2 では問題ありませんでした。Py3でこれを処理するにはどうすればよいですか?

4

4 に答える 4

34

ここで説明されているように、Python 3 では、順序比較演算子は型に関してより厳密です。

順序比較演算子 (<、<=、>=、>) は、オペランドに意味のある自然な順序がない場合、TypeError 例外を発生させます。

Python 2Noneは、任意の文字列 (空の文字列であっても) の前に並べ替えます。

>>> None < None
False

>>> None < "abc"
True

>>> None < ""
True

Python 3 ではNoneType、インスタンスを並べ替えようとすると例外が発生します。

>>> None < "abc"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < str()

私が考えることができる最も簡単な修正は、Noneインスタンスを次のような注文可能なものに明示的にマップすることです"":

my_list_sortable = [(x or "") for x in my_list]

データをそのままの状態でソートしたい場合はsort、カスタマイズされたkeyメソッドを指定してください:

def nonesorter(a):
    if not a:
        return ""
    return a

my_list.sort(key=nonesorter)
于 2012-10-19T09:52:48.990 に答える
32

一般的な解決策として、他のどのオブジェクトよりも比較が少ないオブジェクトを定義できます。

from functools import total_ordering

@total_ordering
class MinType(object):
    def __le__(self, other):
        return True

    def __eq__(self, other):
        return (self is other)

Min = MinType()

Min次に、リスト内のNone値を置き換えるソートキーを使用します

mylist.sort(key=lambda x: Min if x is None else x)
于 2014-10-13T20:47:43.483 に答える