如何按特定键的值对词典列表进行排序?鉴于:

[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]

按名称排序时,应为:

[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]

当前回答

这是另一种通用解决方案——它按键和值对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)
sorted(A, key=sort_key_func)

其他回答

按多个列排序,其中一些列按降序排序:cmps数组是cmp函数的全局数组,包含字段名,对于desc,inv==-1,对于asc

def cmpfun(a, b):
    for (name, inv) in cmps:
        res = cmp(a[name], b[name])
        if res != 0:
            return res * inv
    return 0

data = [
    dict(name='alice', age=10), 
    dict(name='baruch', age=9), 
    dict(name='alice', age=11),
]

all_cmps = [
    [('name', 1), ('age', -1)], 
    [('name', 1), ('age', 1)], 
    [('name', -1), ('age', 1)],]

print 'data:', data
for cmps in all_cmps: print 'sort:', cmps; print sorted(data, cmpfun)

如果不需要字典的原始列表,可以使用自定义键函数使用sort()方法对其进行修改。

关键功能:

def get_name(d):
    """ Return the value of a key in a dictionary. """

    return d["name"]

要排序的列表:

data_one = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]

将其分类到位:

data_one.sort(key=get_name)

如果需要原始列表,请调用sorted()函数,将列表和键函数传递给它,然后将返回的排序列表分配给新变量:

data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
new_data = sorted(data_two, key=get_name)

正在打印data_one和new_data。

>>> print(data_one)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
>>> print(new_data)
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
import operator

要按key='name'对词典列表进行排序:

list_of_dicts.sort(key=operator.itemgetter('name'))

要按key='age'对词典列表进行排序,请执行以下操作:

list_of_dicts.sort(key=operator.itemgetter('age'))

如果性能是一个问题,我会使用operator.itemgetter而不是lambda,因为内置函数比手工制作的函数执行得更快。根据我的测试,itemgetter函数的执行速度似乎比lambda快20%左右。

从…起https://wiki.python.org/moin/PythonSpeed:

同样,内置函数的运行速度也比手工构建的等效函数快。例如,map(operator.add,v1,v2)比map(lambda x,y:x+y,v1,v2)更快。

下面是lambda与itemgetter排序速度的比较。

import random
import operator

# Create a list of 100 dicts with random 8-letter names and random ages from 0 to 100.
l = [{'name': ''.join(random.choices(string.ascii_lowercase, k=8)), 'age': random.randint(0, 100)} for i in range(100)]

# Test the performance with a lambda function sorting on name
%timeit sorted(l, key=lambda x: x['name'])
13 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

# Test the performance with itemgetter sorting on name
%timeit sorted(l, key=operator.itemgetter('name'))
10.7 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

# Check that each technique produces the same sort order
sorted(l, key=lambda x: x['name']) == sorted(l, key=operator.itemgetter('name'))
True

这两种技术都以相同的顺序对列表进行排序(通过在代码块中执行最终语句来验证),但第一种排序速度稍快。

您必须实现自己的比较函数,该函数将通过名称键的值来比较字典。参见PythonInfo Wiki中的排序迷你如何