63

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

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

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

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

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

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

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

谢谢!

4

3 回答 3

91
>>> 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'}]

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

>>> 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'}]

来自评论:@Bakuriu

我敢打赌两者之间没有太大区别,但避免itemgetter了一些开销,因为它tuple在单个操作码(其他字节码)最终调用下标(),构建并返回它......这对解释器来说还有很多工作。CALL_FUNCTIONlambdaBINARY_SUBSCRtuple

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

于 2013-04-18T12:28:26.887 回答
53
from operator import itemgetter

sorted(your_list, key=itemgetter('name', 'age'))
于 2013-04-18T12:28:35.633 回答
0

这是另一种通用解决方案 - 它按键和值对 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)
于 2015-01-22T17:19:49.013 回答