博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于Python的多重排序
阅读量:5306 次
发布时间:2019-06-14

本文共 2699 字,大约阅读时间需要 8 分钟。

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]def cmpf(a, b, key1, key2):     if (a[key1] != b[key1]):             return a[key1] - b[key1]     else:             return a[key2] - b[key2]def rcmpf(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}]>>>

 

转载于:https://www.cnblogs.com/harelion/p/4934407.html

你可能感兴趣的文章
SSL 1120——【USACO 2.4】回家[最短路]
查看>>
Python学习之路:新式类VS经典类
查看>>
Oracle数据库和实例
查看>>
青海行--(7月19日)麦积山石窟
查看>>
《跟我学IDEA》五、快捷键(编码利器)
查看>>
NTP服务器配置
查看>>
04_web基础(七)之jsp
查看>>
BugTracker.NET安装指南
查看>>
openoj的一个小比赛(J题解题报告)poj1703(并查集)
查看>>
pku 1125 Stockbroker Grapevine 第一周训练——最短路
查看>>
【转】OO无双的blocking/non-blocking执行时刻
查看>>
eclipse,python
查看>>
深入理解java集合框架(jdk1.6源码)
查看>>
php截取后台登陆密码的代码
查看>>
选假球的故事
查看>>
ul li剧中对齐
查看>>
关于 linux 的 limit 的设置
查看>>
模块搜索路径
查看>>
线性基学习
查看>>
序列内第k小查询(线段树)
查看>>