文章目录
通过某个关键字排序字典列表
问题
假设有一个字典列表,需求是根据某个或者某几个字典字段来排序这个列表?
解决方法
在上篇文章【Python 通过某个字段将记录分组】中尝试使用过,Python 提供的 operator
模块中的 itemgetter
函数,能够满足要求,按照指定的字段排序这样的数据结构。假设有如下的会员信息,呈现的方式为如下数据结构:
rows = [
{'fname': 'Brian', 'lname': 'Jones', 'uid': 1003},
{'fname': 'David', 'lname': 'Beazley', 'uid': 1002},
{'fname': 'John', 'lname': 'Cleese', 'uid': 1001},
{'fname': 'Big', 'lname': 'Jones', 'uid': 1004}
]
利用 itemgetter()
函数,根据特定的字段排序字典,实现代码如下:
from operator import itemgetter
rows_by_fname = sorted(rows, key=itemgetter('fname'))
rows_by_uid = sorted(rows, key=itemgetter('uid'))
print(rows_by_fname)
print()
print(rows_by_uid)
上述的输出结果为:
[{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'}]
[{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'}]
itemgetter()
函数也支持多个 keys,如下示例:
rows_by_lfname = sorted(rows, keys=itemgetter('lname', 'fname'))
print(rows_by_lfname)
上述代码的输出结果为:
[{'fname': 'David', 'uid': 1002, 'lname': 'Beazley'},
{'fname': 'John', 'uid': 1001, 'lname': 'Cleese'},
{'fname': 'Big', 'uid': 1004, 'lname': 'Jones'},
{'fname': 'Brian', 'uid': 1003, 'lname': 'Jones'}]
代码解析
上述代码中,rows
作为关键字参数传递给 sorted()
内置函数。实际上,这个参数类型是 callable
,并且,从 rows
中接受一个单一元素,然后返回被用来排序的值。itemgetter()
函数就是负责创建 callable
对象的。
operator.itemgetter()
函数有一个被 rows
中的记录用来查找值的索引参数。可以是一个字典键名称(如上示例的 'fname'
),一个整型值或者任何能够传入一个对象的 __getitem__()
方法的值。如果传递多个索引参数(如上述的 'lname', 'fname'
)给 itemgetter()
,它生成的 callable
对象会返回一个包含所有元素值的元组,并且 sorted()
函数会根据这个元组中的元素去排序。
这里提及下 itemgetter()
,有可替代方案 lambda
表达式,示例如下:
rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'],r['fname']))
这种方式也可以使用。当然,使用 itemgetter()
会更快些。如果追求性能的话,建议使用 itemgetter()
。
以上为本篇的主要内容。