简体   繁体   English

如何使用“Nones last”对列表进行排序

[英]How do I sort a list with “Nones last”

I'm sorting a list of dicts by a key: 我正在按键排序一个dicts列表:

groups = sorted(groups, key=lambda a: a['name'])

some of the dicts have name set to None , and Python 2 places None values before any other, so they're placed at the front of the sorted list. 某些dicts的名称设置为None ,而Python 2将None值置于其他任何值之前,因此它们位于排序列表的前面。 A naive fix would be 一个天真的解决方案

groups = sorted(groups, key=lambda a: a['name'] or 'zzzz')

but, obviously, that would not work for any non-Latin names. 但是,显然,这对任何非拉丁名字都不起作用。

What is a nice and Pythonic way of sorting a list containing None values so that those values are placed at the end of the list? 什么是一种很好的Pythonic方法来排序包含None值的列表,以便将这些值放在列表的末尾?

You can do this by keying it on a tuple: 你可以通过在元组上键入它来做到这一点:

groups = sorted(groups, key=lambda a: (a['name'] is None, a['name']))

This works because Python compares tuples lexicographically (on the first element, then on the second to break ties), and because False gets sorted earlier than True. 这是有效的,因为Python按字典顺序比较元组(在第一个元素上,然后在第二个元素上断开关系),并且因为False早于True排序。 A list of groups like 一组像这样的组

[{'name': 0}, {'name': 1}, {'name': 2}, {'name': 3}, {'name': 4}, {'name': None}]

will become 会变成

[(False, 0), (False, 1), (False, 2), (False, 3), (False, 4), (True, None)]

The tuple that starts with True will necessarily end up at the end, and the rest, since the first value ties, will be sorted by the second value. True开头的元组必然会在最后结束,其余的,因为第一个值绑定,将按第二个值排序。

You can create your own "infinity" object: 您可以创建自己的“无限”对象:

from functools import total_ordering

@total_ordering
class Infinity:
    def __eq__(self, other):
        return type(other) == Infinity
    def __lt__(self, other):
        return False

Use it like so: 像这样使用它:

>>> lis = [{'name': 1}, {'name': None}, {'name': 0}, {'name': 2}]
>>> sorted(lis, key=lambda a: Infinity() if a['name'] is None else a['name'])
[{'name': 0}, {'name': 1}, {'name': 2}, {'name': None}]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM