注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性。
Python内置序列函数系列所有文章都以几个术语为基础:可迭代对象(iterable)、迭代器(iterator)、序列(sequence)、生成器(generator)等。若对此不太理解,可移步Python随笔4前面部分查看。
今天接着讨论另外一组有意思的函数:reversed、sorted与函数。
这两个函数之所以放在一起,是因为它们有类似的地方,比如都跟排序有关,都有能实现同样排序功能的方法l.sort()和l.reverse()——假设l是一个可迭代对象。
1.reversed函数
这个函数非常简单,其语法是reversed(seq),返回一个反向排序的序列seq的迭代器。参数只有一个,且必须是序列这种具有反转功能的可迭代对象,比如序列中的字符串、列表、元组等,而不能是字典、集合等数据类型,否则会报错。
这里要强调的是,跟我们想象的不同,reversed(seq)函数返回的是迭代器,而不是seq经过反向排序后的相同数据类型。它也没有改变原序列seq,而是生成了一个新的反向排序的副本的迭代器;seq依然是原来的样子。
t = (1, 2, 3, 5, 4) # 元组。reversed(t) # reversed()函数生成了一个迭代器。Out[78]: t # 经过reversed()函数后没有改变。Out[79]: (1, 2, 3, 5, 4)list(reversed(t)) # 迭代器用list()函数查看。Out[80]: [4, 5, 3, 2, 1]l = ['a', 'd', 'e', 'c', 'b']list(reversed(l))Out[82]: ['b', 'c', 'e', 'd', 'a']
2.sorted函数
sorted函数同样是排序函数,但比reversed函数复杂不少,甚至某种程度上可以说sorted函数包含了reversed函数的功能。
sorted函数具体语法是:sorted(iterable, key=None, reverse=False)——根据iterable(可迭代对象)中的项返回一个新的已排序列表(注意列表两个字,即使iterable是个字符窜,它也会将其转换成列表)。
它有三个参数:
iterable(可迭代对象)——要进行排序的可迭代对象,以序列(列表等)最为常见。
key——指定带有单个参数的函数,用于从iterable(可迭代对象)的每个元素中提取用于比较的键 (例如key=str.lower)。默认值为None(直接比较元素)。key参数在复合型数据类型中用得比较多。
reverse——为一个布尔值,默认为False,即不反向排序。如果设为True,则每个列表元素将按反向顺序比较进行排序。换句话说,reverse=False时是默认的升序排序;reverse=True时是降序排序。觉得reverse这个参数眼熟吗?它其实就是前面reversed函数的另外一种形式,只不过在这里做了参数。
sorted()确保是稳定的。如果一个排序确保不会改变比较结果相等的元素的相对顺序就称其为稳定的——这有利于进行多重排序(例如先按部门、再按薪级排序)。
s = 'guakegua'sorted(s) # sorted()函数返回的是一个**列表**。Out[84]: ['a', 'a', 'e', 'g', 'g', 'k', 'u', 'u']s # s没有改变。Out[85]: 'guakegua'sorted(s, reverse=True) # reverse=True时降序排序。Out[86]: ['u', 'u', 'k', 'g', 'g', 'e', 'a', 'a']
第二个参数key在复合型数据类型中常常与lambda函数搭配,能发挥不一样的效果。
counsellors = (('周瑜', 97), ('郭嘉', 98), ('诸葛亮', 100), ('荀彧', 99), ('鲁肃', 96))# 注意counsellors原本是个元组数据类型,但sorted()之后返回了一个列表类型。sorted(counsellors, key=lambda x: x[1], reverse=True)Out[90]: [('诸葛亮', 100), ('荀彧', 99), ('郭嘉', 98), ('周瑜', 97), ('鲁肃', 96)]
3.reversed、sorted函数都有各自对应的方法
reversed、sorted两个函数都有对应的方法,能实现近似的功能,尤其对于列表这种数据类型来说更是如此。假设给定的列表l,那么reversed(l)和l.reverse()能实现类似的反向排序功能,sorted(l)和l.sort()一样也能实现类似的升序降序排序功能。
l = ['a', 'b', 'd', 'c']l.reverse()l # l经过l.reverse()方法后本身发生了改变。Out[95]: ['c', 'd', 'b', 'a']lOut[96]: ['c', 'd', 'b', 'a']l.sort()l # l经过l.sort()方法后本身发生了改变。Out[98]: ['a', 'b', 'c', 'd']print(l.sort()) None # l.sort()返回值为None。print(l.reverse()) None # l.sort()返回值为None。
当然,它们依然是有区别的,不仅仅是形式不同,尽管的确有时候它们可以互相代替。
Over.