Python3使用sorted函数对列表元素进行多字段排序

Python3 的 sorted 函数相信你们都会,不外乎像下面这种:python

>>> pairs = [('11', 'one'),('3', 'three'), ('2', 'two'),('2', 'zzz'), ('4', 'four')]
>>> sorted(pairs)
[('11', 'one'), ('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four')]

但这或许不是你指望的排序结果。你或许但愿列表元素 ('11', 'one') 最好排在最后边,可是因为 sorted 对字符串默认是按照 ASCII 排序的,而字符串 “11” 的第一个字符在 ASCII 表中处于 “2”、"3" 和 "4"的前边,固然,若是你把这些数字转换成整型而非字符型的话,排序天然不会出现这种问题。sql

而后你会想到 sorted 函数有一个 key 关键字参数,因而你想,那我让字符串长度更长的排在后边总能够了吧,因此你按照这种想法添加以下限制:数据库

>>> sorted(pairs, key=lambda x: len(x[0]))
[('3', 'three'), ('2', 'two'), ('2', 'zzz'), ('4', 'four'), ('11', 'one')]

可是如今的问题是:列表元素 ('11', 'one') 虽然确乎的确已经排在最后边了,但 ('3', 'three') 居然排在了 ('2', 'two') 的前边,这确定是你不想看到的。你因而慢慢冥想,要是能把这些元素存到数据库就行了,这样我就能够用SQL语句了:函数

SELECT field1, field2 FROM test_table ORDER BY LENGTH(field1), field1 ASC, field2 ASC;

但这种排序问题天然用不着动用数据库,杀鸡焉用牛刀,实际上,只要用好杀鸡的这把刀就行了:code

>>> sorted(pairs, key=lambda x: (len(x[0]), x[0]))
[('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four'), ('11', 'one')]
>>> sorted(pairs, key=lambda x: (len(x[0]), x[0], x[1]))
[('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four'), ('11', 'one')]

虽然 sorted 函数的参数说明有说,key 主要是用来选取进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中。可是你能够将多个排序规则用元组的方式组合起来做为 key 中函数的返回值,以此来达到对迭代元素进行多字段排序的效果。对象

固然,对于列表的 sort 函数也有相似的效果,只不过 sorted 是返回排好序的新列表, sort 是对原列表进行修改,使得原列表的顺序发生变化。排序