按可以为 None 的属性对列表进行排序 [英] Sorting list by an attribute that can be None

查看:46
本文介绍了按可以为 None 的属性对列表进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用

对对象列表进行排序

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

但是如果任何列表项具有 attr = None 而不是 attr = 'whatever'

然后我得到一个 TypeError: unorderable types: NoneType() <str()

在 Py2 中这不是问题.我如何在 Py3 中处理这个问题?

解决方案

此处:

<块引用>

排序比较运算符(<、<=、>=、>)引发 TypeError操作数没有有意义的自然顺序时的异常.

Python 2 在任何字符串(甚至是空字符串)之前对 None 进行排序:

<预><代码>>>>无 <没有任何错误的>>>无

在 Python 3 中,任何对 NoneType 实例进行排序的尝试都会导致异常:

<预><代码>>>>无

我能想到的最快捷的解决方法是将 None 实例显式映射到诸如 "" 之类的可排序内容:

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

如果你想在保持数据完整的情况下对数据进行排序,只需给 sort 一个自定义的 key 方法:

def nonsorter(a):如果不是:返回 ""返回一个my_list.sort(key=nonsorter)

I'm trying to sort a list of objects using

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

but if any of the list items has attr = None instead of attr = 'whatever',

then I get a TypeError: unorderable types: NoneType() < str()

In Py2 it wasn't a problem. How do I handle this in Py3?

解决方案

The ordering comparison operators are stricter about types in Python 3, as described here:

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.

Python 2 sorts None before any string (even empty string):

>>> None < None
False

>>> None < "abc"
True

>>> None < ""
True

In Python 3 any attempts at ordering NoneType instances result in an exception:

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

The quickest fix I can think of is to explicitly map None instances into something orderable like "":

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

If you want to sort your data while keeping it intact, just give sort a customized key method:

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

my_list.sort(key=nonesorter)

这篇关于按可以为 None 的属性对列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆