通过公共键对字典列表进行排序

假如有一个list,其中每个子项都是一个dict,现在要根据dict中的公共键进行排序。

我们知道,sorted函数有一个关键字参数key,可以定制排序用到的算法。比如,我们有一个从数据库中获取到的一组用户,数据如下:

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

现在,我们想根据“fname”进行排序,我们可以编写如下的代码:

rows_by_fname = sorted(rows, key=lambda r: r['fname'])
rows_by_lfname = sorted(rows, key=lambda r: (r['lname'], r['fname']))

这是常规的代码写法,但Python标准库的operator模块提供了一个更为便捷,且性能更强大的函数,叫做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(rows_by_uid)

itemgetter()函数也可以接受多个key组成一个元祖。

rows_by_lfname = sorted(rows, key=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'}]

operator.itemgetter()函数将查找索引作为参数,用于从行中的记录中提取所需的值。 它可以是字典键名,数字列表元素,也可以是可以提供给对象的__getitem __()方法的任何值。 如果给itemgetter()赋予多个索引,它产生的callable将返回一个包含其中所有元素的元组,sorted()将根据元组的排序顺序对输出进行排序。 如果要同时对多个字段(例如姓氏和名字进行排序,如示例中所示),这可能很有用。

posted @ 2019-08-04 22:55  Jeffrey_Yang  阅读(243)  评论(0编辑  收藏  举报