python123动物重量排序_关于Python的多重排序
Python预置的list.sort()、sorted()方法可实现各种数组的排序,但支持的只限于一个key,如果要多重排序,目前所知的方法只有自定义了。
Help on built-in function sorted in module __builtin__:
sorted(...)
sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list
查看sorted的帮助可知,cmp参数在第二个位置,不过一般都以kwargs的形式显式写出。
关于cmp,cmp定义的函数接收源数组中相邻的两个元素,在比较大小后分别返回负值、0或正值,分别代表第一个值小于、等于或大于第二个值,然后再按照key和reverse的设定去进行排序。
>>> a=list(range(10))>>>a.reverse() # reverse为on place方法>>>a
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]>>> a.sort(cmp=lambda a,b: a-b) # a-b < 0 默认reverse为False,升顺排序,结果为正常顺序>>>a
[0,1, 2, 3, 4, 5, 6, 7, 8, 9]>>> a.sort(cmp=lambda a,b: b-a) # b-a > 0 lambda返回正值,认为a > b,按照“升顺”排序,实际结果为降序>>>a # sort同样是on place方法
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]>>>
对于多重排序,可利用cmp方法,分别定义key的优先级,以及排序方式,达到多重、独立顺序的排序方式实现。
代码如下:
d1 = {1:23, b: 62}
d2= {1:24, b: 2}
d3= {1:23, b: 54}
d4= {1:23, b: 1}
d5= {1:01, b: 9}
d6= {1:23, b: 32}
d7= {1:05, b: 33}
d8= {1:39, b: 100}
li=[d1, d2, d3, d4, d5, d6, d7, d8]defcmpf(a, b, key1, key2):if (a[key1] !=b[key1]):return a[key1] -b[key1]else:return a[key2] -b[key2]defrcmpf(a, b, key1, key2):if (a[key1] !=b[key1]):return b[key1] -a[key1]else:return a[key2] -b[key2]#key1、key2均为升序
sorted(li, cmp=lambda a,b: cmpf(a, b, 1, b))#key1降序、key2升序
sorted(li, cmp=lambda a,b: rcmpf(a, b, 1, b))
执行结果如下:
>>> sorted(li, cmp=lambda a,b: cmpf(a, b, 1, b))
[{1: 1, b: 9}, {1: 5, b: 33}, {1: 23, b: 1}, {1: 23, b: 32}, {1: 23, b: 54}, {1: 23, b: 62}, {1: 24, b: 2}, {1: 39, b: 100}]>>>
>>> sorted(li, cmp=lambda a,b: rcmpf(a, b, 1, b))
[{1: 39, b: 100}, {1: 24, b: 2}, {1: 23, b: 1}, {1: 23, b: 32}, {1: 23, b: 54}, {1: 23, b: 62}, {1: 5, b: 33}, {1: 1, b: 9}]>>>
可以看到混合排序结果正常。
PS:按照预想,这种方式应该适用于所有可以指定多个key的数据结构,不过仍待验证。
对于Python3,sort方法取消了cmp参数,官方给出的解决方案是进行多次排序,优先级低的字段先排序,然后逐个根据优先级高的字段排序
>>> d1 = {1:23, b: 62}>>> d2 = {1:24, b: 2}>>> d3 = {1:23, b: 54}>>> d4 = {1:23, b: 1}>>> d5 = {1:1, b: 9}>>> d6 = {1:23, b: 32}>>> d7 = {1:5, b: 33}>>> d8 = {1:39, b: 100}>>> li =[d1, d2, d3, d4, d5, d6, d7, d8]>>> li.sort(key=lambda e: e[b]) #现根据b进行排序,优先级较低
>>>pprint(li)
[{1: 23, b: 1},
{1: 24, b: 2},
{1: 1, b: 9},
{1: 23, b: 32},
{1: 5, b: 33},
{1: 23, b: 54},
{1: 23, b: 62},
{1: 39, b: 100}]>>> li.sort(key=lambda e: e[1]) #再根据1进行排序,优先级高于b
>>>pprint(li)
[{1: 1, b: 9},
{1: 5, b: 33},
{1: 23, b: 1},
{1: 23, b: 32},
{1: 23, b: 54},
{1: 23, b: 62},
{1: 24, b: 2},
{1: 39, b: 100}]>>>
