如何按特定键的值对词典列表进行排序?鉴于:
[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}]
按名称排序时,应为:
[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}]
如何按特定键的值对词典列表进行排序?鉴于:
[{'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中的排序迷你如何