2024-05-19 16:35:45 发布
网友
我正在尝试使用
my_list.sort(key=operator.attrgetter(attr_name))
但是如果列表项中的任何一个有attr = None而不是attr = 'whatever'
attr = None
attr = 'whatever'
然后我得到一个TypeError: unorderable types: NoneType() < str()
TypeError: unorderable types: NoneType() < str()
在Py2中这不是问题。在Py3里我该怎么处理?
排序比较运算符对Python 3中的类型更加严格,如here:
The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.
Python 2在任何字符串(甚至是空字符串)之前对None排序:
None
>>> None < None False >>> None < "abc" True >>> None < "" True
在Python 3中,任何排序NoneType实例的尝试都会导致异常:
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方法:
sort
key
def nonesorter(a): if not a: return "" return a my_list.sort(key=nonesorter)
对于一般解决方案,可以定义一个比任何其他对象都小的对象:
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()
然后使用排序键替换列表中的任何None值Min
Min
mylist.sort(key=lambda x: Min if x is None else x)
这里提出的解决方案是可行的,但可以进一步缩短:
mylist.sort(key=lambda x: x or 0)
从本质上讲,我们不能把任何一个当作值为0的。
例如:
>>> mylist = [3, 1, None, None, 2, 0] >>> mylist.sort(key=lambda x: x or 0) >>> mylist [None, None, 0, 1, 2, 3]
排序比较运算符对Python 3中的类型更加严格,如here:
Python 2在任何字符串(甚至是空字符串)之前对
None
排序:在Python 3中,任何排序
NoneType
实例的尝试都会导致异常:我能想到的最快的解决方法是显式地将
None
实例映射到""
这样的可排序对象:如果您想在保持数据完整性的同时对数据进行排序,只需给
sort
一个定制的key
方法:对于一般解决方案,可以定义一个比任何其他对象都小的对象:
然后使用排序键替换列表中的任何
None
值Min
这里提出的解决方案是可行的,但可以进一步缩短:
从本质上讲,我们不能把任何一个当作值为0的。
例如:
相关问题 更多 >
编程相关推荐