1. sort函数
sort函数为python内置的列表排序高阶函数,所谓高阶函数,也就是参数为函数或返回值为函数。
先看个简单的例子:
# 数字列表的排序示例
nums = [5, 2, 9, 1, 7] nums.sort()
print(nums) # 输出:[1, 2, 5, 7, 9]
可以发现排序后,改变了原列表的顺序。而且sort()函数没有返回值,或者说返回值是None。再看sort函数的语法:
sort函数的语法是:list.sort(key=None, reverse=False)。
参数说明:
key:指定用于排序的函数,可以指定一个函数,这个函数接受一个参数并返回一个用于排序的关键字,默认为None,表示按照列表的元素排序,但是要求每个元素的数据类型相同。
reverse:如果为True,则列表会以降序排序,默认为False,即升序排序。
nums = [5, 2, 9, 1, 7] nums.sort(reverse=True) print(nums) # 输出:[9, 7, 5, 2, 1] #如果是字符,元素就应该统一全部是字符,按照编码大小比较。 nums = ['5', '2', '9','T' '1', '7','!','t','1'] nums.sort(reverse=True) print(nums) # 输出:['t', 'T1', '9', '7', '5', '2', '1', '!']
如果每个元素为列表或元组、字典,在key=None的情况下又该如何比较大小呢?
当key=None时:
- 元素为列表的列表排序
讲解元素为列表的列表之前先看个代码:
list01=[3,1] list02=[0,1,1] print(list01>list02)#True
可以看到是先比较两个列表元素的第一个,显然3>0,运算结果是True(如果相等,继续比较后面的,注意,并不是比较列表的长度大小)。
再看下面例子:
# 比较时,相互比较的元素数据类型要相同,否则报错 list01=[3,1] list02=['0',1,1] print(list01>list02)#报错报错报错TypeError: '>' not supported between instances of 'int' and 'str'
还有一种特殊的例子:
list01=[3,1] list02=[0,'1',1] print(list01>list02)#True
这种情况不会报错,因为比较第一个元素时,已经能分出大小了。
元素为列表的排序先看2个例子,再分析。
lst1=[[0,1],[1,1,2]] lst2=[[1,1],[0,2]] print(lst1>lst2)#False lst1=[[1,1],[1,1,2]] lst2=[[1,1],[2,2]] print(lst1>lst2)#False
所以,当元素为列表时,依然按照前面的方法比较大小,lst中的第一个元素[0,1]和lst中的第一个元素[1,1]比较大小,[0,1]与[1,1]比较大小再次按照列表的比较大小规则即可。下面为key=None时,调用sort后的排序例子。
mylist = [[1, 1, 0], [2, 0], [1, 2], [1, 1], [2, 0, 3], [3], [2], [1, 2, 3, 4, 5]] mylist.sort() print(mylist)#[[1, 1], [1, 1, 0], [1, 2], [1, 2, 3, 4, 5], [2], [2, 0], [2, 0, 3], [3]]
通过上面例子可以发现,当key=None时,排序规则和列表的简单排序一样,比如[1,1,0]>[1,1],前面两个元素相等时,就看长度,长度大的大。
- 元素为元组的列表
先说元组,由于sort是对原址排序,而元组内部不可修改,所以直接对元组是不能排序的。但是,我们的数据类型是列表,列表的每一个元素是元组,由于整体是列表类型,当然可以调用sort函数排序了。先看元组如何比较大小:
print((4,2)>(2,3))#True print((4,2)>(2,2,1))#True
也就是说元组比较大小和简单列表比较大小的规则相同。
tuple1=[(4,2),(2,3),(3,1)] tuple1.sort() print(tuple1)#[(2, 3), (3, 1), (4, 2)]
- 元素为字典的列表
先看个例子:
dict1 = {'a': 1, 'b': 2} dict2 = {'b': 2, 'a': 1} dict3 = {'a': 1, 'b': 3} print(dict1 == dict2) # True,与顺序无关 print(dict1 == dict3) # False print(dict1 > dict3) # 报错TypeError: '>' not supported between instances of 'dict' and 'dict'
两个字典不能直接比较大小,==(调用了__eq__()函数)是比较内容是不是一样的。所以元素为字典的列表是不能直接调用sort函数排序的。
当key不为None:
按照自定义的规则进行排序。我们需要给key传入一个函数作为参数,按照函数的规则进行排序。这个函数接受一个参数并返回一个用于排序的关键字。具体是什么意思呢?先看个简单的例子:
lst=[[1, 2], [1, 1], [2, 0], [6, 3,0], [1, 2,3]] def sort_by_first_element(lst): return lst[0] lst.sort(key=sort_by_first_element) print(lst)#[[1, 2], [1, 1], [1, 2, 3], [2, 0], [6, 3, 0]]
将参数传入给了sort函数的key,观察排序的结果,可以发现上面代码元素的排序是按照每个元素(仍然是列表)的第一个元素进行比较大小的,不比较第二个元素,若第一个元素相等,则两个元素相等,不改变顺序,比如[1,2]与[1,1]按照排序规则是相等的。进一步,观察sort_by_first_element这个函数,返回值是lst[0]。似乎返回的是[1,2]。又是怎么做到比较每一个元素(列表)的第一个元素的呢?仔细思考,sort_by_first_element(lst):中的lst其实是形参,另外,可以发现一定是sort函数内部实现了排序,其根据给定原始列表信息lst及函数sort_by_first_element返回值是能实现排序结果的,也就是说想要返回元素的第一个元素,那么sort_by_first_element(lst)中的lst可能传入参数时像这样:sort_by_first_element(lst[0]),sort_by_first_element(lst[1])等,再返回lst[0]时,就真正做到了返回元素的第一个元素。这里用自己的方法实现一下sort函数(猜测python内部可能采用了快速排序用C语言实现了sort函数,实现排序)。代码如下:
""" MyLIst类定义了sort方法用于对列表排序 ""&quo