Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

3.2.6 通过关键字排序字典

在操作列表时,对于列表中的元素是字典的情形,我们有时需要根据某个或某几个字典字段来排序这个列表。

使用operator模块的itemgetter()函数,可以非常容易地排序这样的数据结构。

假设从数据库中检索出学生的信息列表,并以下列的数据结构返回,代码如下:


student_info = [
    {'name': 'xiao meng', 'age': 12, 'number': 1003},
    {'name': 'xiao ming', 'age': 12, 'number': 1002},
    {'name': 'xiao zhi', 'age': 11, 'number': 1001},
    {'name': 'xiao li', 'age': 12, 'number': 1004}
]

现根据任意的字典字段来排序输入结果行,代码如下:


from operator import itemgetter

student_info = [
    {'name': 'xiao meng', 'age': 12, 'number': 1003},
    {'name': 'xiao ming', 'age': 12, 'number': 1002},
    {'name': 'xiao zhi', 'age': 11, 'number': 1001},
    {'name': 'xiao li', 'age': 12, 'number': 1004}
]

order_by_name = sorted(student_info, key=itemgetter('name'))
order_by_number = sorted(student_info, key=itemgetter('number'))
print(order_by_name)
print(order_by_number)

itemgetter()函数支持多个key,示例如下:


order_by_name_age = sorted(student_info, key=itemgetter('name','age'))
print(order_by_name_age)

在示例中,student_info被传递给接收一个关键字参数的sorted()内置函数。这个参数是callable类型,从student_info中接收一个单一元素,然后返回被用来排序的值。itemgetter()函数负责创建callable对象。

operator.itemgetter()函数中有一个索引参数,student_info通过这个索引参数从记录中查找值。索引参数可以是一个字典键名称、一个整型值,也可以是任何能够传入__getitem__()方法的值。如果传入多个索引参数给itemgetter()函数,它生成的callable对象会返回一个包含所有元素值的元组,并且sorted()函数会根据该元组中元素顺序去排序。如果想同时在几个字段上进行排序(比如通过name和age来排序),这种方法是很有用的。

有时候,itemgetter()函数也可以用lambda表达式代替,示例如下:


order_by_name = sorted(student_info, key=lambda r: r['name'])
order_by_age_number = sorted(student_info, key=lambda r: (r['age'],r['number']))
print(order_by_name)
print(order_by_age_number)

使用lambda表达式的方案也不错,但是使用itemgetter()函数会运行得稍微快点。如果对性能要求比较高,建议使用itemgetter()函数。

这里展示的技术同样适用于min()和max()等函数,示例如下:


print(min(student_info, key=itemgetter('number')))
print(max(student_info, key=itemgetter('number')))