python学习笔记05:排序
1. list内置方法sort()
语法:sort(key=None, reverse=False)
参数:
key,一个函数,作用是指定比较的元素, 通常由lambda指定, 可以指定多个值lambda x: (x[0], x[1], x[2]);
reverse,bool类型,False升序,True降序, 默认升序;
说明:
sort方法会改变list本身, 并返回None, 所以不能这么写a = b.sort();
python3中,sort删除了cmp参数
例子:
>>> L0 = [('a', 1), ('b', 3), ('d', 2), ('c', 1)]
>>>
>>> # 默认排序
>>> L0.sort()
>>> L0
[('a', 1), ('b', 3), ('c', 1), ('d', 2)]
>>>
>>> # key=lambda x:x[1], 按L0元素(是一个tuple)的第1个元素排序,
>>> # 也可以指定key=lambda x:(x[1], x[0])进行多维排序
>>> L0.sort(key=lambda x:x[1])
>>> L0
[('a', 1), ('c', 1), ('d', 2), ('b', 3)]
>>>
>>> # 降序排序
>>> L0.sort(reverse=True) # 默认按升序排序,通过reverse=True按降序排列;
>>> L0
[('d', 2), ('c', 1), ('b', 3), ('a', 1)]
>>>
>>> # sort返回值是None, 即list.sort()没返回任何对象
>>> print(L0.sort())
None
2. 全局方法sorted()
语法:sorted(iterable, key=None, reverse=False)
参数:
iterable: 可迭代对象
key:sorted是一个高阶函数,可以接收一个key函数来自定义排序,key指定的函数作用于list的每一个元素上,并根据key函数的返回值进行排序, 参见list的内置函数sort的key参数.
reverse:bool类型,False升序,True降序; 默认升序.
注意:sorted方法不改变原序列,而是返回一个新的序列;
例1:按绝对值排序、按忽略大小写排序、降序排序
>>> sorted([36,15,-12,9,-21], key=abs) #按绝对值大小排序;
[9, -12, 15, -21, 36]
>>> sorted(['bob', 'About', 'Zoo', 'Credit'], key=str.lower) # 按忽略大小写排序;
['About', 'bob', 'Credit', 'Zoo']
>>> sorted(['bob','About','Zoo','Credit'], key = str.lower, reverse=True) # 按忽略大小写反向排序;
['Zoo', 'Credit', 'bob', 'About']
例2:按字典的key/value排序
>>> d={}
>>> d['a'] = 3
>>> d['b'] = 4
>>> d['c'] = 2
>>> d['d'] = 1
>>> sorted(d.items(), key=lambda x:x[0]) #按key排序,返回[('a',3),('b',4),('c',2),('d',1)]
>>> sorted(d.items(), key=lambda x:x[1]) #按value排序,返回[('d',1),('c',2),('a',3),('b',4)]
例3:按多条件排序
>>> d0 = {}
>>> d0['id0'] = {'score':90, 'name':'name1', 'age':14}
>>> d0['id1'] = {'score':90, 'name':'name3', 'age':12}
>>> d0['id2'] = {'score':60, 'name':'name2', 'age':13}
>>> d0['id3'] = {'score':90, 'name':'name3', 'age':11}
>>>
>>> list_id_sorted = sorted(
... d0.keys(), # 对d0.keys()排序, 所以返回的是id组成的list.
... key=lambda s_id:(
... -d0[s_id]['score'], # 按分数逆序排列,-表示逆序
... d0[s_id]['name'] , # 按姓名顺序排列
... s_id , # 按学号顺序排列
... )
... )
...
>>> for s_id in list_id_sorted:
... print(f'{d0[s_id]['score']} {d0[s_id]['name']} {s_id}')
...
90 name1 id0 # 90分排在前;
90 name3 id1 # 同样90分,按姓名排序;
90 name3 id3 # 同样90分,同样name3,按学号排序;
60 name2 id2 # 60分排在后;
3. key参数
key参数
可以是一个简单的函数, 比如key=str或key=str.lower,
可以是一个通过lambda指定的函数 key=lambda x:(x[0], x[1])
可以是一个自定义的函数:
def sort_str(x):
m = re.match(r'^(\S+?)(\d+)$', x)
if m:
_name = m.group(1)
_idx = int(m.group(2))
else:
_name = x
_idx = 0
return _name, idx # 先按前导字符排序, 后按后缀数字排序
# 这样'a2'排在'a10'前面, 'a*'排在'b0'前面.
L0 = ['a2', 'b3', 'a1', 'b20', 'a0', 'a10', 'a9', 'b0']
L1 = sorted(L0, key=sort_str)
print(L1) # ['a0', 'a1', 'a2', 'a9', 'a10', 'b0', 'b3', 'b20']