概述
【干货】python sorted()函数超详尽教程(附lambda函数教程)(上)(下篇还在赶工)
作者: MELATONIN_T
转载之前请私信:CSDN平台的用户 MELATONIN_T
目录
- 【干货】python sorted()函数超详尽教程(附lambda函数教程)(上)(下篇还在赶工)
- 0. 前言
- 1. sorted()函数的介绍
- 1.1 sorted()函数的作用
- 1.1.0 概述
- 1.1.1 sorted的排序规则
- - 数字
- - 字符串
- - 布尔值
- 小结
- 1.2 sorted()函数的参数
- 1.2.1 iterable 可迭代对象
- - 当iterable是字典时
- - 当iterable是一个嵌套的可迭代对象时
- 1.2.2 reverse
- 1.2.3 key
- 小结
- 2. 如何解决多排序规则问题
- 2.1 什么是多排序规则问题?
- 2.2 巧妙地使用元组来辅助排序
- 小结
0. 前言
sorted()函数作为一个内置函数(built-in function),在python中的使用频率比较高。我相信,基本上所有的python程序员都懂得如何使用sorted()函数。但是,并不是所有python程序员都懂得如何把sorted()用得更pythonic,更优雅。
在本文中,我将带领大家从sorted()函数的基本开始,详细介绍sorted()函数的运用,包括如何使用lambda。
本教程将分上下两篇,上篇主要介绍sorted()函数的基本功能与如何解决多规则的排序问题。下篇则围绕着lambda函数展开。希望大家在看完本教程之后能有所收获。
在学习本教程之后,大家应该仅能利用一行代码解开以下问题:
# 排序问题 : 排序规则:奇数<偶数<小写字母<大写字母。奇偶数,大小写字母各自内部分别按照升序排列。
['A', 2, 3, 'g', 4, 1]
# 答案例:[1, 3, 2, 4, 'g', 'A']
那么,就让我们开始教程吧。
1. sorted()函数的介绍
1.1 sorted()函数的作用
1.1.0 概述
什么是sorted()函数? 它是用来干什么的?
用官方文档里的话来说:The sorted() function returns a sorted list from the items in an iterable. “sorted函数会返回一个排好顺序的可迭代对象的列表。”
用人话来说:我们给sorted一个可以排序(准确来说是迭代)的东西,sorted会把它排好序,变成列表还给你。
什么叫排好序? sorted中的排序规则有哪些呢?我们一起来看下一节。
1.1.1 sorted的排序规则
sorted()函数非常强大,可以给字符串,列表,元组,字典,集合等可迭代对象进行排序。
>>>sorted([2, 3, 1])
[1, 2, 3]
就像上面的例子一样,在默认的情况下,列表中的数字会按照从小到大的顺序被排序。这就是sorted的一种排序规则。
在这一节中,我将带着大家了解(基本)所有的python sorted()函数的排序规则。
- 数字
sorted()中数字的默认排序规则是升序排列。
这里说的数字不仅是int整数型,也可以包含float。我们来看一个例子。
>>>nums = [2.6, 3, 1, 1/3, -1]
>>>sorted(nums)
[-1, 0.3333333333333333, 1, 2.6, 3]
可以看到,无论是整数,小数,负数,还是计算式, sorted函数都会默认地把他们(和计算式的结果)从小到大排序。
- 字符串
字符串也是可以被排序的,原因,一言以蔽之,因为它是可迭代对象,因为它可以被for…in…
就像这样:
s = "python"
for char in s:
print(char)
# results
p
y
t
h
o
n
我们使用了for…in…打印了字符串中的每一个字母。
(为什么我会重点强调可迭代对象这个问题我会在 1.2 sorted()函数的参数 中讲解)
既然字符串可以被排序,那它一定有一个排序规则。没有规则,根本无法进行排序。比如"a"在"b"之前,"b"在"c"之前,就是一种排序规则。在sorted中,字符串是如何被排序的呢?
字符串的排序规则很直观,不是按照ascii码,sorted会按照英文的字母表和字母的大小写进行排序。例如:
a<b<c<d<…<z
A<a, B<b, …, Z<z
如上所示,字母表越前面的字母越小,越后面的字母越大。一个字母的大写小于他的小写。
这里提一个小问题:不同字母的大小写之间如何比较大小呢?
还不了解的同学可以执行一下下面的代码看看
print("A" < "g")
print("G" < "a")
结果是
True
True
这背后的原因是:字符串的排序规则是“所有的大写字母都小于小写字母”。用图片解释比较直观,就不多赘述了,请看下图:
lst1 = list("abcdefgABCDEFG")
print(sorted(lst1))
# result
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'a', 'b', 'c', 'd', 'e', 'f', 'g']
这个例子里,所有的大写字母都被sorted排到了小写字母之前,而大小写字母内部是按照字母表顺序进行排列的。
用两句话总结字符串的排序规则:“所有的大写字母都小于小写字母”,“大小写相同时按字母表排序”
- 布尔值
布尔值有且只有两种:True和False
True
False
虽然看起来不太可能,但布尔值其实也是可以比较大小的。这一令人吃惊的现象背后的原因在于布尔值对象是整数对象的子类。可以直观地理解为:
True == 1
False == 0
布尔值也可以被看作是整数的0和1。
Python官方文档如是说:
The two objects representing the values False and True are the only Boolean objects. The Boolean type is a subtype of plain integers, and Boolean values behave like the values 0 and 1.
废话少说,上代码解释:
print(False + True)
print(True + True)
print(False * True)
print(True * True)
print(True / True)
print(100 * True)
print("布尔值的举动就和整数的举动一样 False == 0, True == 1")
# results
1
2
0
1
1.0
100
布尔值的举动就和整数的举动一样 False == 0, True == 1
是不是感觉非常神奇?
所以如果我们让sorted给一串布尔值进行排序的话,结果就和一串0和1的排序没有差别。0在前,1在后;False在前,True在后
b = [True, False, True, False]
print(sorted(b))
# result
[False, False, True, True]
小结
在这一节中,我们讨论了sorted的排序规则。用三句话总结来说就是整数升序排列,字符串先大写后小写按照字母表,布尔值先False后True。
在下一节中,我们将着眼sorted函数的参数,解释为什么我在这一节强调了“可迭代对象”这个词,以及进一步地探索sorted()函数的妙用。
1.2 sorted()函数的参数
sorted()函数可以接受三个参数
- iterable: 可迭代对象
- reverse(optional): reverse == True 或 False, 接受布尔值,默认值False
- key(optional): 接受函数,默认值None
写出来是这么个形式:
sorted(iterable, reverse = False, key = None)
接下来我会详细介绍这三个形式参数。
1.2.1 iterable 可迭代对象
我在上一节中就提到过可迭代对象。可迭代对象的标志就是可以被for…in…语法从其中顺次拿到数据进行使用。用术语来说,一个可以被遍历的对象叫做可迭代对象。
其实有个更准确的定义,一个具备了__iter__方法的对象(或者说迭代器协议),就是一个可迭代对象。但鉴于本文的主题并不是可迭代对象,就不在此赘述了。感兴趣的小伙伴可以上百度或谷歌搜索iterable进行学习。
常见的可迭代对象有:list、tuple、dict、set、str等等。下面是对列表,元组,字符串分别使用sorted()函数的例子。
下面讲几种需要特殊注意的情况。
- 当iterable是字典时
当我们把字典作为iterable的实际参数传给sorted()函数时,返回值会是一个列表,这个列表的内容是这个字典排好序的键。
dic = {
"Tom": "13",
"Alice": "14",
"Bob": "15",
"alice": "16",
}
print(sorted(dic))
# result
['Alice', 'Bob', 'Tom', 'alice']
有趣的是,这个字典的键被按照首字母来排序了(Alice的A,Bob的B,Tom的T,最后是alice的a)。这个例子这正是我们下面要讲的可迭代对象的嵌套。可迭代对象的嵌套究竟是如何被sorted()函数排序的呢?我们一起来看下一小节。
- 当iterable是一个嵌套的可迭代对象时
嵌套的可迭代对象的简单例子:
{"": [], "": [],"": []}
[(), (), ()]
([], [], [])
以上三个例子分别是:字典中嵌套列表,列表中嵌套元组,元组中嵌套列表。(省略了其中的元素)
嵌套的可迭代对象的比较是通过比较所有的,对应结构的嵌套最底层的第一个元素实现的。如果第一个元素一致,就会比较下一个元素。来看一个例子:
A = (1, 2 ,3)
B = (3, 1, 2)
C = ((2, 1), 3)
D = (2, (1, 3))
print(A < B)
print(B < D) # 注意不是 B < C
# result
True
False
注意!!!如果嵌套结构不一致的话会报错
A = (1, 2 ,3)
B = (3, 1, 2)
C = ((2, 1), 3)
D = (2, (1, 3))
print(B < C)
# result
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-13-599bb9711cb1> in <module>()
3 C = ((2, 1), 3)
4 D = (2, (1, 3))
----> 5 print(B < C)
TypeError: '<' not supported between instances of 'int' and 'tuple'
报错的原因是嵌套结构不一样导致了sorted把元组(2, 1)和整数2进行了比较。所以发生了TypeError: ‘<’ not supported between instances of ‘int’ and ‘tuple’
如果第一个元素一致,就会比较下一个元素:
A = (1, 1, 2)
B = (1, 2, 3)
print(A < B)
# result
True
再总结一下,嵌套的可迭代对象的比较是通过比较所有的,对应位置的最底层的第一个元素实现的。如果第一个元素一致,就会比较下一个元素,一直到分出大小为止。
1.2.2 reverse
reverse这个形式参数接受布尔值,它的默认值是False。
我们用一个例子来比较一下reverse == False 和 reverse == True 时sorted()函数的行为:
如图所示,我们将列表lst = [2, 3, 1, 4, 5]传给函数sorted。
当reverse == False或者不输入的时候,返回的结果是[1, 2, 3, 4, 5];当reverse == True的时候,返回的结果是[5, 4, 3, 2, 1]
reverse == True会让sorted()函数的排序规则反过来。
reverse = False(默认)的排序规则:
整数升序排列,字符串先大写后小写按照字母表,布尔值先False后True。
而当reverse == True时,排序规则就变成了:
整数降序排列,字符串先小写后大写按照反过来的字母表,布尔值先True后False。
1.2.3 key
在key中可以输入自己声明的函数或者Python内置的函数作为排序的标准。
使用Python内置函数的例子:
# 在sorted中使用python自带的函数/方法
# 转载之前请私信:CSDN平台的用户 MELATONIN_T
lst = ['4345' ,'d', '24', 'b', '3', 'c']
sorted_lst_isdigit = sorted(lst, key = str.isdigit)
sorted_lst_len = sorted(lst, key = len)
print("sorted_lst_isdigit: ", sorted_lst_isdigit)
print("sorted_lst_len: ", sorted_lst_len)
# results
sorted_lst_isdigit: ['d', 'b', 'c', '4345', '24', '3']
sorted_lst_len: ['d', 'b', '3', 'c', '24', '4345']
在这个例子中,我们分别传给sorted() .isdigit()方法和len()函数。
key == str.isdigit时,按照是否为数字排序。返回的元组字母在前(False),数字在后(True)
key == len时,按照字符串长度排序。字符串越长,排在越后面。长度相同时按照原来的顺序排。(而不是按照字母表或者数字大小排。因为我们自定义了排序规则,所以sorted将不按照默认规则进行排序。)
自己声明函数的例子:
在这个例子中,我们声明了函数sort_with_second_num;旨在以每个元组中的第二个元素的大小作为排序规则。
实际输出的结果[(3, 1), (1, 2), (2, 3)]确实遵守了这个规则。
小结
在这一小节中,我们讨论了sorted()函数的三个参数;测试了sorted()函数在iterable是不同形式时的不同表现;在最后学习了如何使用Python内置函数和自己定义的函数作为排序的key。
在下一节中,我们将学习如何应对拥有两个或两个以上排序规则的排序问题。
2. 如何解决多排序规则问题
在这一节中,我们将学习如何应对拥有两个或两个以上排序规则的排序问题。比起我们方才学习的排序问题(比如按照每个元组中的第二个元素的大小作为排序规则),这一类型的问题在实际操作中更加常见。
在学习完这一节后,我们应该能轻松面对如下问题:
# 元素:(学生名字, 学生成绩,学生年龄)
# 要求成绩从低到高,成绩一样的按照年龄从小到大排
students_list = [
("Alice", 90, 18),
("Peter", 75, 20),
("Bob", 90, 20),
("Jane", 80, 19),
("Jack", 80, 21),
]
# answer
[('Peter', 75, 20), ('Jane', 80, 19), ('Jack', 80, 21), ('Alice', 90, 18), ('Bob', 90, 20)]
2.1 什么是多排序规则问题?
有时候我们需进行排序操作的对象的规则不止一个。
例如:小红想要谈朋友,开出的第一个条件是男方的身高,越高越好,3米最好(打个比方而已);如果有身高一样的男同胞就按照月收入来排序,月收高的优先。
虽然很现实很残酷,小红将会一个男朋友也没有,孤寡一生,但这恰恰就是一个有两个规则的排序问题的很好的例子。在这个例子中我们需要两个key:1.身高 2.月收。
为此我们需要在参数key中做一些文章。
2.2 巧妙地使用元组来辅助排序
为了更好地理解如何使用元组来辅助我们解决问题,我们再来温习一下元组的排序规则。
>>>(1, 2) < (1, 3)
True
>>>(1, 2) < (2, 2)
True
>>>(1, 2, 3)< (3, 4)
True
一图胜千言。
处理多排序规则问题的关键就在于让我们传给key的函数返回一个元组 — 然后我们利用这个元组进行排序。
小红的问题中,我们要让key中的函数返回
(身高, 月收)
结果传给sorted()之后,sorted()会先比较元组中的第一个元素“身高”,如果身高一样,就会比较月收。程序如下
def sorter(males: list):
height = males[0]
salary = males[1]
return (height, salary) # 让函数返回(身高, 月收)
# 可供小红选择的对象
tom = [160, 50000, "汤姆"]
jack = [180, 3000, "杰克"]
gaofushuai = [180, 50000, "高富帅"]
males = [tom, jack, gaofushuai]
# key = sorter,让sorted用元组(身高, 月收)排序
sorted_males = sorted(males, key = sorter)
print(sorted_males)
print(f"最终小红选择了{sorted_males[2][2]}")
#result
[[160, 50000, '汤姆'], [180, 3000, '杰克'], [180, 50000, '高富帅']]
最终小红选择了高富帅
值得注意的是,我们在def sorter(males):
这一行里给sorter传的参数是一个列表。
这是因为sorter会顺次的访问被排序对象中的每一个元素(这个例子是写有每一位男方信息的列表),然后把它传给key。
这节开头的问题同学们会解答了吗?
我会把答案贴在下面(仅作参考)
# 元素:(学生名字, 学生成绩,学生年龄)
# 要求成绩从低到高,成绩一样的按照年龄从小到大排
students_list = [
("Alice", 90, 18),
("Peter", 75, 20),
("Bob", 90, 20),
("Jane", 80, 19),
("Jack", 80, 21),
]
# answer
[('Peter', 75, 20), ('Jane', 80, 19), ('Jack', 80, 21), ('Alice', 90, 18), ('Bob', 90, 20)]
小结
在这一节中,我们学习了如何应对拥有两个或两个以上排序规则的排序问题。
在接下来的python sorted()函数详尽教程(下)中,我们将接触lambda匿名函数,并了解如何在在sorted()中使用lambda来解决实际问题。
-
lambda匿名函数的介绍
-
在sorted()中使用lambda
让我们下篇再见!(还在赶工中)
最后
以上就是醉熏蜻蜓为你收集整理的【干货】python sorted()函数详尽教程(附lambda函数教程)(上)【干货】python sorted()函数超详尽教程(附lambda函数教程)(上)(下篇还在赶工)0. 前言1. sorted()函数的介绍2. 如何解决多排序规则问题的全部内容,希望文章能够帮你解决【干货】python sorted()函数详尽教程(附lambda函数教程)(上)【干货】python sorted()函数超详尽教程(附lambda函数教程)(上)(下篇还在赶工)0. 前言1. sorted()函数的介绍2. 如何解决多排序规则问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复