Python:如何按多个值对字典列表进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16082954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 21:44:13  来源:igfitidea点击:

Python: How to sort a list of dictionaries by several values?

pythonlistsorting

提问by Joko

I want to sort a list at first by a value and then by a second value. Is there an easy way to do this? Here is a small example:

我想首先按一个值对列表进行排序,然后再按第二个值排序。是否有捷径可寻?这是一个小例子:

A = [{'name':'john','age':45},
     {'name':'andi','age':23},
     {'name':'john','age':22},
     {'name':'paul','age':35},
     {'name':'john','age':21}]

This command is for sorting this list by 'name':

此命令用于按以下方式排序此列表'name'

sorted(A, key = lambda user: user['name'])

But how I can sort this list by a second value? Like 'age'in this example.

但是我如何按第二个值对这个列表进行排序?就像'age'在这个例子中一样。

I want a sorting like this (first sort by 'name'and then sort by 'age'):

我想要这样的排序(首先排序'name',然后排序'age'):

andi - 23
john - 21
john - 22
john - 45
paul - 35

Thanks!

谢谢!

采纳答案by jamylak

>>> A = [{'name':'john','age':45},
     {'name':'andi','age':23},
     {'name':'john','age':22},
     {'name':'paul','age':35},
     {'name':'john','age':21}]
>>> sorted(A, key = lambda user: (user['name'], user['age']))
[{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}]

This sorts by a tuple of the two attributes, the following is equivalent and much faster/cleaner:

这按两个属性的元组排序,以下等效且更快/更清晰:

>>> from operator import itemgetter
>>> sorted(A, key=itemgetter('name', 'age'))
[{'age': 23, 'name': 'andi'}, {'age': 21, 'name': 'john'}, {'age': 22, 'name': 'john'}, {'age': 45, 'name': 'john'}, {'age': 35, 'name': 'paul'}]

From the comments: @Bakuriu

来自评论:@Bakuriu

I bet there is not a big difference between the two, but itemgetteravoids a bit of overhead because it extracts the keys and make the tupleduring a single opcode(CALL_FUNCTION), while calling the lambdawill have to call the function, load the various constants(which are other bytecodes) finally call the subscript (BINARY_SUBSCR), build the tupleand return it... that's a lot more work for the interpreter.

我敢打赌两者之间没有太大区别,但itemgetter避免了一点开销,因为它tuple在单个操作码(CALL_FUNCTION)期间提取密钥并制作,而调用lambda将不得不调用该函数,加载各种常量(它们是其他字节码) 最后调用下标 ( BINARY_SUBSCR),构建tuple并返回它......这对解释器来说是更多的工作。

To summarize: itemgetterkeeps the execution fully on the Clevel, so it's as fast as possible.

总结一下:itemgetter让执行完全保持在C水平上,所以它尽可能快。

回答by Jon Clements

from operator import itemgetter

sorted(your_list, key=itemgetter('name', 'age'))

回答by vvladymyrov

Here is the alternative general solution - it sorts elements of dict by keys and values. The advantage of it - no need to specify keys, and it would still work if some keys are missing in some of dictionaries.

这是替代的通用解决方案 - 它按键和值对 dict 的元素进行排序。它的优点 - 无需指定键,如果某些字典中缺少某些键,它仍然可以工作。

def sort_key_func(item):
    """ helper function used to sort list of dicts

    :param item: dict
    :return: sorted list of tuples (k, v)
    """
    pairs = []
    for k, v in item.items():
        pairs.append((k, v))
    return sorted(pairs)