关于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]
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}]
>>>
关于Python的多重排序的更多相关文章
- Python复杂多重排序
1. cmp函数是python自带的函数,用于比较两个参数哪个大哪个小 print cmp(2, 3) # -1 如果第一个参数比第二个小,就返回-1,两个元素相等,返回0,否则返回1 2.所以就可以 ...
- Python:如何排序(sort)
一.前言 对Python的列表(list)有两个用于排序的方法: 一个是内建方法list.sort(),可以直接改变列表的内容: >>> list1 = [9,8,7,6,5] &g ...
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- 帮初学者改代码——有多少青春可以挥霍之“c语言 多重排序”
原文:“c语言 多重排序” 原代码: #include<stdio.h> #include<string.h> struct A { char name[100]; int g ...
- Python的列表排序
Python的列表排序 本文为转载,源地址为:http://blog.csdn.net/horin153/article/details/7076321 在 Python 中, 当需要对一个 list ...
- 飘逸的python - 多条件排序及itemgetter的应用
曾经客户端的同事用as写一大堆代码来排序,在得知python排序往往只需要一行,惊讶无比,遂对python产生浓厚的兴趣. 之前在做足球的积分榜的时候需要用到多条件排序,如果积分相同,则按净胜球,再相 ...
- Python 冒泡法排序
def sequence(disorder='', separators=''): arrays = disorder.split(separators) def desc(): for i in r ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- 深入Python(1): 字典排序 关于sort()、reversed()、sorted()
http://www.cnblogs.com/BeginMan/p/3193081.html 一.Python的排序 1.reversed() 这个很好理解,reversed英文意思就是:adj. 颠 ...
随机推荐
- 【[SCOI2008]奖励关】
又抄了一篇题解 要凉了要凉了,开学了我还什么都不会 文化课凉凉,NOIP还要面临爆零退役的历史进程 这道题挺神的,期望+状态压缩 我们设\(dp[i][S]\)表示在第\(i\)天前,捡的宝物状态为\ ...
- how to design Programs 学习笔记
how to design Programs 学习笔记 */--> how to design Programs 学习笔记 目录 1. 前言 1.1. 系统化程序设计 1.2. 输入和输出 2. ...
- 如何选择PHP项目的开发方案?
我说的项目开发方案并不是谈论到底用不用PHP去开发的问题,而是当你遇到一个项目,已经决定了用PHP,然后才来看的问题:用PHP的什么开发方案. 基本上有这么几种方案.各有各的说法,良莠不齐,我就谈谈我 ...
- Kali-linux应用更新和配置额外安全工具
本节将介绍更新Kali的过程和配置一些额外的工具.这些工具在后面的章节中将是有用的.Kali软件包不断地更新和发布之间,用户很快发现一套新的工具比最初在DVD ROM上下载的软件包更有用.本节将通过更 ...
- vue.js加入购物车小球动画
生成一个动画小球的div,并且生成五个小球,五个是为了生成一定数量的小球来作为操作使用,按照小球动画的速度,一般来说五个也可以保证有足够的小球数量来运行动画 动画的内容分别是外层和内层,外层控制动画小 ...
- GIS中的空间参考
GIS一般都是研究的基于地球的某个区域,例如一个国家.省或市的情况,既然地球上都有经纬度来标识,那么直接用经纬度来标识物体的位置不可以吗?但如果应用不一样,在实际中选择的空间参考系也是不一样的.例如我 ...
- C#XML格式字符串取节点数据
XML格式的字符串: <xml><return_code><![CDATA[{0}]]></return_code><return_msg> ...
- Andorid进阶7—— Ant自动编译打包&发布 android项目
http://www.cnblogs.com/tt_mc/p/3891546.html Eclipse用起来虽然方便,但是编译打包android项目还是比较慢,尤其将应用打包发布到各个渠道时,用Ecl ...
- Google Fonts导致网页加载速度慢
最近在做商城项目时候发现在加载一个html页面反应非常慢,查看发现是Google Font导致的网页加载速度缓慢,删除掉该样式会发现很多内容出错. 上网百度发现问题在于: 谷歌香港(google.co ...
- 课时18.h标签和p标签以及hr标签(掌握)
如何在webstorm中利用快捷键创建一个新的html的文件? 同时按下键盘上的ctrl+alt+insert(windows) 同时按下键盘上的ctrl+alt+n(os) h标签系列(header ...