Python中sort与sorted函数
python中列表的内置函数sort()可以对列表中的元素进行排序,而全局性的sorted()函数则对所有可迭代的序列都是适用的;
并且sort()函数是内置函数,会改变当前对象,而sorted()函数只会返回一个排序后的当前对象的副本,而不会改变当前对象。
sort
原型:sort(fun,key,reverse=False)
参数fun是表明此sort函数是基于何种算法进行排序的,一般默认情况下python中用的是归并排序,并且一般情况下我们是不会重写此参数的,所以基本可以忽略;
参数key用来指定一个函数,此函数在每次元素比较时被调用,此函数代表排序的规则,也就是你按照什么规则对你的序列进行排序;
参数reverse是用来表明是否逆序,默认的False情况下是按照升序的规则进行排序的,当reverse=True时,便会按照降序进行排序。
#coding:utf-8
from operator import attrgetter,itemgetter list1 = [(2,'huan',23),(12,'the',14),(23,'liu',90)] #使用默认参数进行排序,即按照元组中第一个元素进行排序
list1.sort()
print list1
#输出结果为[(2, 'huan', 23), (12, 'the', 14), (23, 'liu', 90)] #使用匿名表达式重写key所代表的函数,按照元组的第二个元素进行排序
list1.sort(key=lambda x:(x[1]))
print list1
#[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)] #使用匿名表达式重写key所代表的函数,按照元组的第三个元素进行排序
list1.sort(key=lambda x:(x[2]))
print list1
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] #使用匿名函数重写key所代表的函数,先按照元组中下标为2的进行排序,
# 对于下标2处元素相同的,则按下标为0处的元素进行排序
list1.sort(key=lambda x:(x[2],x[0]))
print list1
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] #使用operator模块中的itemgetter函数进行重写key所代表的函数,按照下标为1处的元素进行排序
list1.sort(key=itemgetter(1))
print list1
#[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)] #使用operator模块中的itemgetter函数进行重写key所代表的函数,按照下标为2处的元素进行排序
list1.sort(key=itemgetter(2))
print list1
# [(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] # 此处可以类比lambda中的排序方法,就不再解释
list1.sort(key=itemgetter(2,0))
print list1
#[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]
sorted
原型sorted(iterable, cmp=None, key=None, reverse=False)
对于sorted()函数中key的重写,和sort()函数中是一样的,所以刚刚对于sort()中讲解的方法,都是适用于sorted()函数中
cmp函数:
# 排序算法:
# 排序也是在程序中经常用到的算法。
# 无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。
# 如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。
# 通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,
# 这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序 # Python内置的sorted()函数就可以对list进行排序:
print(sorted([34, 5, 7, 2, 8, 13])) print('-----------------------------------------------------------------------------------') # sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
# 比如,如果要倒序排序,我们就可以自定义一个reversed_self函数
# 传入自定义的比较函数reversed_self,就可以实现倒序排序
def reversed_self(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
res = sorted([34, 5, 7, 2, 8, 13], reversed_self)
print(res) print('-----------------------------------------------------------------------------------') # 默认情况下,对字符串排序,是按照ASCII的大小比较的,由于'Z' < 'a',结果,大写字母Z会排在小写字母a的前面。
# 现在,我们提出排序应该忽略大小写,按照字母序排序。要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以
# Python upper() 方法将字符串中的小写字母转为大写字母。
def ignore_case(x1, x2):
u1 = x1.upper()
u2 = x2.upper()
if u1 < u2:
return -1
if u1 > u2:
return 1
return 0
# 忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较
res1 = sorted(['bob', 'about', 'Zoo', 'Credit'], ignore_case)
print(res1)
sort与sorted函数比较
sorted() 作用于任意可迭代的对象,而 sort() 一般作用于列 表。
因此下面的例子中针对元组使用 sort() 方法会抛出 AttributeError,而使用 sorted() 函数则 没有这个问题。
>>> a = (1,2,4,2,3)
>>> a.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'sort'
>>> sorted(a)
[1, 2, 2, 3, 4]
当排序对象为列表的时候两者适合的场景不同。sorted() 函数会返回一个排序后的列表,原有列表保持不 变;而 sort() 函数会直接修改原有列表,函数返回为 None。
>>> a=['',1,'a',3,7,'n']
>>> sorted(a)
[1, 3, 7, '', 'a', 'n']
>>> a
['', 1, 'a', 3, 7, 'n']
>>> print a.sort()
None
>>> a
[1, 3, 7, '', 'a', 'n']
因此如果实际应用过程中需要保留原有列表,使用 sorted() 函数较为适合,否则可以选 择 sort() 函数,因为 sort() 函数不需要复制原有列表,消耗的内存较少,效率也较高。
无论是 sort() 还是 sorted() 函数,传入参数 key 比传入参数 cmp 效率要高。cmp 传入 的函数在整个排序过程中会调用多次,函数开销较大;而 key 针对每个元素仅作一次处理, 因此使用 key 比使用 cmp 效率要高。
sorted的强大功能
对字典进行排序(中根据字典的值进行排序)
>>> phonebook = {'Linda': '', 'Bob': '', 'Carol': ''}
>>> from operator import itemgetter
>>> sorted_pb = sorted(phonebook.iteritems(),key=itemgetter(1))
>>> print sorted_pb
[('Carol', ''), ('Linda', ''), ('Bob', '')]ps: iteritems()方法返回字典的迭代器对象。 operator.itemgetter()函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号)。看例子
a = [1,2,3]
>>> b=operator.itemgetter(1) //定义函数b,获取对象的第1个域的值
>>> b(a)
2
>>> b=operator.itemgetter(1,0) //定义函数b,获取对象的第1个域和第0个的值
>>> b(a)
(2, 1) 要注意,operator.itemgetter函数获取的不是值,而是定义了一个函数,通过该函数作用到对象上才能获取值。多维list排序
实际情况下也会碰到需要对多个字段进行排序的情况,如根据学生的成绩、对应的等级依次排序。当然这在 DB 里面用 SQL 语句很容易做到,但使用多维列表联合 sorted() 函数也可以轻易达到类似的效果。
>>> from operator import itemgetter
>>> gameresult = [['Bob',95.00,'A'],['Alan',86.0,'C'['Mandy',82.5,'A'],['Rob',86,'E']] # 分别表示学生的姓名,成绩,等级
>>> sorted(gameresult , key=operator.itemgetter(2, 1))
[['Mandy', 82.5, 'A'], ['Bob', 95.0, 'A'], ['Alan', 86.0, 'C'], ['Rob', 86, 'E']] # 当第二个字段成绩相同的时候按照等级从低到高排序字典中混合list排序
如果字典中的 key 或者值为列表,需要对列表中的某一个位置 的元素排序也是可以做到的。看例子:
针对字典 mydict 的 value 结构 [n,m] 中的 m 按照从小到大的顺序排列。
>>> mydict = { 'Li' : ['M',7],
... 'Zhang': ['E',2],
... 'Wang' : ['P',3],
... 'Du' : ['C',2],
... 'Ma' : ['C',9],
... 'Zhe' : ['H',7] }
>>>
>>> from operator import itemgetter
>>> sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v))
[('Zhang', ['E', 2]), ('Du', ['C', 2]), ('Wang', ['P', 3]), ('Li',['M', 7]), ('Zhe', ['H', 7]), ('Ma', ['C', 9])]字典中混合list排序
列表中的每一个元素为字典形式,需要针对字典的多个key 值进行排序也不难实现。
看例子: 针对 list 中的字典元素按照 rating 和 name进行排序的实现方法。>>> gameresult = [
{ "name":"Bob", "wins":10, "losses":3, "rating":75.00 },
... { "name":"David", "wins":3, "losses":5, "rating":57.00 },
... { "name":"Carol", "wins":4, "losses":5, "rating":57.00 },
... { "name":"Patty", "wins":9, "losses":3, "rating": 71.48 }]
>>> from operator import itemgetter
>>> sorted(gameresult , key=operator.itemgetter("rating","name"))
[
{'wins': 4, 'losses': 5, 'name': 'Carol', 'rating': 57.0},
{'wins': 3, 'losses': 5, 'name': 'David', 'rating': 57.0},
{'wins': 9, 'losses': 3, 'name': 'Patty','rating': 71.48},
{'wins': 10, 'losses': 3, 'name': 'Bob', 'rating': 75.0}]PS python2 与python3区别
sorted(iterable, cmp=None, key=None,reverse=False) ## Python 2.x sorted(iterable, key=None,reverse=False) ## Python 3.x
由此可看出,Python3.x取消了 cmp参数, 所以如果想给 sorted()函数传参的话,就剩下 key,和reverse了。
也就是说我们无法直接传入多个参数的函数进行排序
如果直接写的话,会发现
## 报错信息如下:
TypeError: must use keyword argument
for
key function
类型错误: 必须使用关键字参数。
那么我们该如何解决这个问题呢?
那就是使用functools中的cmp_to_key,即在开头加上
from functools import cmp_to_key
from functools import cmp_to_key
def desc(color1_list,color2_list):
if len(color1_list) == 0:
return -1
else:
if len(color2_list) == 0:
return 1
if color1_list[0] > color2_list[0]:
return 1
else:
return -1
sameList = sorted(sameTypeList,key = cmp_to_key(desc))
Python中sort与sorted函数的更多相关文章
- Python中sort和sorted函数代码解析
Python中sort和sorted函数代码解析 本文研究的主要是Python中sort和sorted函数的相关内容,具体如下. 一.sort函数 sort函数是序列的内部函数 函数原型: L.sor ...
- Python中sort以及sorted函数初探
sorted(...) Help on built-in function sorted in module __builtin__: sorted(...) sorted(iterable, cmp ...
- Python中sort、sorted的cmp参数废弃之后使用cmp_to_key实现类似功能
Python2.1以前的排序比较方法只提供一个cmp比较函数参数,没有__lt__等6个富比较方法, Python 2.1引入了富比较方法,Python3.4之后作废了cmp参数.相应地从Python ...
- python中sort和sorted排序的相关方法
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列. 1)排序基础 简单的升序排序是非常容易的.只需要调用sorte ...
- python中sort()与sorted()的区别
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...
- python中sort和sorted用法的区别
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 一,最简单的排序 1.使用sort排序 my_list = [3 ...
- Python中sort、sorted的cmp参数废弃之后使用__lt__支持复杂比较的方法
Python2.1以前的排序比较方法只提供一个cmp比较函数参数,没有__lt__等6个富比较方法, Python 2.1引入了富比较方法,Python3.4之后作废了cmp参数.相应地从Python ...
- python中sort与sorted区别
1.sort()函数 (只对list有用) sort(...) L.sort(key = None,reverse=False) key = 函数 这个函数会从每个元素中提取一个用于比较的关键字.默认 ...
- 为什么Python中sort方法和sorted函数调用废弃使用cmp参数
Python中sort方法和sorted函数老猿在前面一些章节介绍过,具体语法及含义在此不再展开说明,但老猿在前面学习相关内容时,只使用了简单的案例,对这两个方法的key参数没有深入研究,总以为就是以 ...
随机推荐
- 启动tomcat7w.exe提示"指定的服务未安装"
说下本人的情况:因为重装系统,安装在C盘的tomcat的失去作用.想要启动tomcat7w.exe(这是管理服务的)出现“指定服务未安装,无法打开tomcat7服务”的提示.原因是重装系统也导致之前安 ...
- 一分钟理解js闭包
什么是闭包?先看一段代码: ? 1 2 3 4 5 6 7 8 9 10 function a(){ var n = 0; function inc() { n++; cons ...
- VBA程序的调试
VBA程序的调试:设置断点.单步跟踪.设置监视窗 Acces的VBE编程环境提供了完整的一套调试工具和调试方法.熟练掌握好这些调试工具和调试方法的使用,可以快速.准确地找到问题所在,不断修改,加以完善 ...
- SQL语句优化方法30例
1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化. 例如: SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_I ...
- dpkg安装工具
dpkg --info "软件包名" --列出软件包解包后的包名称. dpkg -l --列出当前系统中所有的包.可以和参数less一起使用在分屏查看. (类似于rpm -qa) ...
- xshell 使用密钥登录
http://blog.csdn.net/suquan629/article/details/44783377
- 使用readelf和objdump解析目标文件 ***
引言 本文是对程序员的自我修养:链接.装载与库中第3章的实践总结(和结构相关的示意图都是用Gliffy Diagrams画的
- linux文件系统命令和分区 挂载
文件系统命令df [选项][挂载点]选项:-a 显示所有的文件系统信息,包括特殊文件,如/proc,/sysfs-h 使用习惯单位显示容量,如KB,MB或GB等-T 显示文件系统类型-m 以MB为单位 ...
- windows抓包工具Wireshark(过滤)
1.IP过滤 ip.src ==192.168.0.208(ip.src eq 192.168.0.208) //来源等于某个ip ip.dst ==192.168.0.208(ip.dst eq 1 ...
- 什么是闭包?在js中的作用是什么?
闭包就是讲函数内部生成的变量保存到内存中,进行下次调用:也可以说函数外不可以调用函数内部的变量: 当函数内部返回一个函数时,闭包搭建了方法内部与方法外部的桥梁,使得外部也可以任意的获取到方法内部的资源 ...