目录
高阶函数: 高阶函数英文叫 Higher-order function。编写高阶函数,就是让函数的参数能够接收别的函数。把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。高阶函数以及迭代函数还可以帮我们省去使用循环遍历元素的操作,在内部已经帮我们实现好了!
一、all()函数——判断可迭代对象中的元素是否全为True
all() 函数用于判断可迭代对象是否包括假值即 0、空、False,除此之外都属于真值。如果包括假值结果就为 False,否则结果就为 True。all() 函数的语法格式如下:
In [7]: all?
Signature: all(iterable, /)
Docstring:
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.
Type: builtin_function_or_method
参数说明:
- iterable:可迭代对象,如列表、元组等。参数不能为空并且提供的参数必须是可迭代器对象,否则将提示 TypeError 错误信息。
- 返回值:返回值为 True 或 False,如果可迭代对象不包括空、0、False 的元素,那么返回值为 True,否则返回值为 False。
示例代码:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 20:51
# @Author : AmoXiang
# @File: all_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
import random # 导入随机数模块
# 1.使用all()函数判断可迭代对象是否包括空、0、False的元素
print(all([1, 3, 5, 7, 9])) # 列表元素都不为空、0、False,返回True
print(all(('Python', 'Java'))) # 元组元素都不为空、0、False,返回True
print(all([0, 2, 4, 6, 8])) # 列表元素中存在一个为0的元素,返回False
print(all(['a', 'b', 'c', ''])) # 列表元素中存在一个为空的元素,返回False
# 如果可迭代对象中元素个数为0,则返回值为True,例如空列表、空元组、空字典的返回值为True
print(all([])) # 空列表,返回True
print(all(())) # 空元组,返回True
print(all({})) # 空字典,返回True
# all()函数以一个可迭代器对象为参数,当参数为空或者提供的参数不是可迭代器对象时
# 将提示TypeError错误信息
# 将提示TypeError: all() takes exactly one argument (0 given)
# print(all()) # 参数不能为空
# 将提示TypeError: 'int' object is not iterable
# print(all(2)) # 参数必须为可迭代对象
# 2.判断列表中是否包括0
while 1:
a = [random.randint(0, 5) for _ in range(5)] # 生成0-5之间的随机数列表
if all(a):
print(a)
break
else:
print('随机数列表中没有0,程序重新执行!')
二、any()函数——判断可迭代对象是否全为假值
any() 函数用于判断可迭代对象元素是否都是假值即 0、空、False。如果全部为假值则返回 False,否则返回 True。any() 函数的语法格式如下:
In [8]: any?
Signature: any(iterable, /)
Docstring:
Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, return False.
Type: builtin_function_or_method
参数说明:
- iterable:可迭代对象,如列表、元组、字符串等。同样的,参数不能为空并且提供的参数必须是可迭代器对象,否则将提示 TypeError 错误信息。
- 返回值为 True 或 False,如果可迭代对象中只要有一个元素不是假值,则返回值为 True,如果可迭代对象中所有的元素都是假值,则返回值为 False。
示例代码:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 20:57
# @Author : AmoXiang
# @File: any_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 使用any()函数判断下列可迭代对象是否全为假值
a1 = any(['python', 'java', 'c++', '.net', ' '])
a2 = any([0, 1, 2, 3, 4, 5]) # 有一个元素为True,则返回True
a3 = any([0, '', False]) # 全部元素为False,则返回False
a4 = any((0, 0))
a5 = any([]) # 可迭代对象为空(元素个数为0),返回False
# 输出判断结果
print('第一个序列:', a1)
print('第二个序列:', a2)
print('第三个序列:', a3)
print('第四个序列:', a4)
print('第五个序列:', a5)
# 如果可迭代对象为空(元素个数为0),返回值为False,如空列表、空元组返回值为False。
print(any(()))
print(any([]))
# 将提示TypeError: any() takes exactly one argument (0 given)
# print(any()) # 参数不能为空
# 将提示TypeError: 'int' object is not iterable
print(any(2)) # 参数必须为可迭代对象
三、filter()函数——通过指定条件过滤序列
filter() 函数用于过滤掉可迭代对象中不符合条件的元素,返回由符合条件的元素组成的新的迭代器。filter() 函数把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。filter() 函数的语法格式如下:
In [9]: filter?
Init signature: filter(self, /, *args, **kwargs)
Docstring:
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.
Type: type
Subclasses:
参数说明:
- function:用于实现判断的函数。注意:这里的函数指的是函数的名字,不要打()调用。
- iterable:可迭代对象,如列表、range 对象等。
- 返回值:返回一个迭代器对象。
示例:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 21:01
# @Author : AmoXiang
# @File: filter_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 1.filter()函数的基本应用
def even_number(num): # 定义一个判断偶数的函数
return num % 2 == 0
filter1 = filter(even_number, range(100)) # 使用filter()函数过滤出序列中的偶数
print(filter1) # 返回一个迭代器对象
print(list(filter1)) # 使用list()函数将迭代器转换为列表
# 2.筛选指定范围的数据
def find(item): # 创建函数
total = int(item[1])
if 600 <= total < 700: # 判断条件
return True
return False
list1 = [('小明', 600), ('小刚', 601), ('小雅', 524), ('小旭', 714),
('小章', 624), ('小白', 635), ('小赵', 480),
('小高', 580), ('小王', 541), ('小琪', 680)]
newList = filter(find, list1) # 过滤序列中不符合条件的元素
list2 = list(newList) # 使用list()函数转换为列表
print(list2) # 输出学生列表
print('600分以上:', len(list2), '人') # 输出人数
# 3.筛选类型不是字符的元素
a = {'amo', 123, 12.1, -1}
print(set(filter(lambda x: isinstance(x, (int, float)), a)))
# 4.取出字符串中的数字并转换为整型
a1 = 'ISVO20N2WTRJ4T0XXGQ5QWP9Z'
a2 = filter(str.isdigit, a1) # 过滤数字
a3 = list(a2) # 转换为列表
num = ''.join(a3) # 连接列表
print(int(num)) # 转换为整型输出
【示例5】去除序列中所有值为假的元素。如果将 filter() 函数的第一个参数 function 的值设置为 None,就会默认去除序列中所有值为假的元素,如 None、False、0、‘’、()、[] 和 {}等,代码如下:
L = [1, '', 0, 'C', None, [0, 1, 2], False, 3.14, [], {'c': 1, 3: None}, {}]
f = filter(None, L) # 去除序列中为假的元素
print(list(f)) # [1, 'C', [0, 1, 2], 3.14, {'c': 1, 3: None}]
【示例6】获取序列中被删除的元素。filter() 函数的返回值是一个可迭代对象,利用 for 循环将返回数据与原始数据比较,就可以判断出哪些元素被删除了。代码如下:
L = [1, '', 0, 'C', None, [0, 1, 2], False, 3.14, [], {'c': 1, 3: None}, {}]
f = list(filter(None, L))
print(f)
delete_data = L
for i in f:
if i in L:
delete_data.remove(i)
print(f"被删除的元素为: {delete_data}")
【示例7】获取索引中以索引为基数所对应的元素。通过 filter() 和 lambda() 函数输出列表 list_a 中以索引为基数出现次数最多的元素。代码如下:
list_a = [12, 213, 22, 2, 2, 2, 22, 2, 2, 32]
li = filter(lambda x: x in list_a, [i for i in range(len(list_a))])
print(list(li)) # [2]
【示例8】判断是否已经收藏某课程。在线课堂项目中,用户可以收藏喜欢的课程。如果之前已经收藏过该课程,则不用收藏。所以每次收藏之前,需要查询该课程是否已经收藏。代码如下:
class Course(object):
"""
课程类
"""
def __init__(self, course_id):
self.course_id = course_id
# 判断是否已经收藏
def is_favorite(course_id):
# 获取所有收藏的课程 id
course = list(filter(lambda c: c.course_id == course_id, course_list))
if len(course) > 0:
return True
return
if __name__ == '__main__':
course_list = []
for i in range(1, 10):
# 实例化9个课程类,并传递课程id
course_list.append(Course(i))
print(is_favorite(7)) # True
print(is_favorite(10)) # None
四、map()函数————通过函数实现对可迭代对象的操作
map() 函数接收一个函数为参数和一个或者多个可迭代对象为参数,返回一个迭代器。此迭代器中每个元素都是函数参数依次作用于可迭代对象后的结果。map()函数的语法格式如下:
In [11]: map?
Init signature: map(self, /, *args, **kwargs)
Docstring:
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
Type: type
Subclasses:
参数说明:
- func:函数。
*iterables
: 一个或多个可迭代对象。- 返回值:返回迭代器。
注意:map()函数在Python 2.x返回的是列表,而在Python 3.x中返回的是可迭代器对象。
【示例1】将列表中的元素转换为Unicode字符。
num1 = [25105, 29233, 80, 89]
a = map(chr, num1) # 返回一个迭代器对象
print(a)
print(list(a)) # 使用list()函数转换为列表
运行程序,输出结果为:
<map object at 0x00000243A720A520>
['我', '爱', 'P', 'Y']
从程序的运行结果可以看出,map() 函数返回的是一个可迭代器对象,我们通过使用 list() 函数将其转换为列表。
【示例2】规范英文的大小写。通过map()函数规范英文短句中单词的大小写(即首字母大写,其余字母小写),代码如下:
name_list = ['Being', 'SinGle', 'IS', 'better', 'than',
'being', 'in', 'an', 'unfaithful', 'relationship'] # 创建列表
def function(x): # 定义函数
return x.capitalize() # 实现首字母大写,其他字母小写
print("规范后的英文短句:", list(map(function, name_list))) # 使用list()函数转换为列表
aa = list(map(function, name_list))
print(' '.join(aa)) # 连接列表
【示例3】对列表中的元素进行平方计算。
num_list = [i for i in range(10)] # 创建空列表
list2 = map(lambda x: x ** 2, num_list) # 返回一个迭代器对象
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print(list(list2)) # 使用list()函数转换为列表
【示例4】传入多个可迭代对象。当使用map()函数传入多个可迭代对象时,且里面的元素长度不一致时,生成的迭代器以最短长度为主,例如下面的代码:
list1 = [1, 3, 5] # 列表1
list2 = [2, 4, 6, 8, 10] # 列表2
result = map(lambda x, y: x + y, list1, list2) # 返回一个迭代器对象
# [3, 7, 11]
print(list(result)) # 使用list()函数转换为列表
注意:当map()函数传入多个可迭代对象时,参数function必须能够接收足够多的参数,以保证每个可迭代对象同一索引的值均能正确传入函数,否则将出现错误提示TypeError。
【示例5】使用 map 函数实现数据类型转换。实现将随机生成的三位数的数字分割为列表,首先将数字转换成字符型,但此时列表中的元素也同时变成了字符型数字,这时还需要通过 map() 函数对数据类型进一步转换为整型。例如,数字 612 ⇒ [‘6’,‘1’,‘2’] ⇒ [6,1,2],代码如下:
import random
# 随机生成10个三位数的数字
data_list = random.sample(range(100, 1000), 10)
for i in data_list:
# 将随机的三位数分割为列表,并使用map()函数将字符型数字转换为整型
print(str(i))
num_list = list(map(int, str(i)))
print(num_list)
五、range()函数——生成器函数
range() 函数用于生成一个新的 range 类型,多用于 for 循环语句中,用于生成指定范围的整数。range() 函数的语法格式如下:
range(start,end,step)
参数说明:
- start:表示起始整数(包含起始整数),默认起始值为 0,起始整数可以省略,如果省略则表示从 0 开始。
- end:表示结束整数(但不包括该值,如 range(7) 得到的值为 0~6,不包括7),结束数值不能省略。当 range() 函数中只有一个参数时,即表示指定计数的结束值。结束整数可以大于 0,也可以小于或等于 0,但是结束整数小于或等于 0 时,生成的 range 对象是不包含任何元素的。
- step:表示步长,即两个数之间的间隔,参数 step 可以省略,如果省略则表示步长为 1。例如,range(1,7) 将得到 1、2、3、4、5、6。
- 返回值:返回一个 range 对象。
range()函数接收的参数必须是整数,不能是浮点数等其他数据类型,否则会提示类型错误。在使用range()函数时,如果只有一个参数,那么表示指定的是stop结束整数;如果是两个参数,则表示指定的是start开始整数和end结束整数;只有三个参数都存在时,最后一个参数才表示step步长。
示例:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 21:21
# @Author : AmoXiang
# @File: range_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 1.根据提供的参数生成一个range类型
print(range(15))
print(range(50, 100, 1))
print(range(50, 100, 10))
# 2.使用list()函数将range类型转换为列表
print(list(range(0))) # 参数为0,生成的列表不包含任何元素
print(list(range(-88))) # 参数为负数,生成的列表不包含任何元素
print(list(range(9))) # 不包括9
print(list(range(5, 15))) # 不包括15
print(list(range(10, 100, 10))) # 不包括100,步长为10
print(list(range(10, 101, 5))) # 包括100,步长为5
# 3.使用range()函数实现数字的累加
result = 0 # 保存累加结果的变量
for i in range(101):
result += i # 实现累加功能
print(result) # 在循环结束时输出结果
# 4.遍历字符串
str1 = 'Python'
for i in range(len(str1)):
print(str1[i])
# 5.生成指定步长的数值序列
num1 = range(2, 14, 2)
num2 = range(1, 13, 2)
print('偶数月份:', end=' ') # 输出偶数月份
for i in num1:
print(i, end=' ')
print('\n', end='') # 换行
print('奇数月份:', end=' ') # 输出奇数月份
for i in num2:
print(i, end=' ')
六、reversed()函数——反转序列对象
reversed() 函数用于反转一个序列对象,将其元素从后向前颠倒构建成一个新的迭代器,reversed() 函数的语法格式如下:
In [13]: reversed?
Init signature: reversed(sequence, /)
Docstring: Return a reverse iterator over the values of the given sequence.
Type: type
Subclasses:
参数说明:
- sequence:序列,如列表、元组、字符串或 range 对象等。
- 返回值:返回一个反转的迭代器。
【示例1】反转迭代器对象转换为列表后输出。
str1 = reversed('amo') # 定义字符串
print(str1) # 返回一个反转的迭代器
print(list(str1)) # 使用list()函数将可迭代对象转换为列表
list1 = [1001, 888, 999, 666] # 列表
print(list(reversed(list1)))
num = range(0, 101, 10) # range对象
print(list(reversed(num)))
tuple1 = ('Python', 'Java', 'C语言') # 元组
print(list(reversed(tuple1)))
运行程序,输出结果为:
<reversed object at 0x00000279954C5790>
['o', 'm', 'a']
[666, 999, 888, 1001]
[100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
['C语言', 'Java', 'Python']
【示例2】反转数字列表并排序。定义一个保存Python成绩的列表,然后使用sort()方法排序,使用reversed()函数对列表反转,实现降序排序,代码如下:
num_list = [100, 85, 56, 59, 75, 77] # 分数列表
num_list.sort() # 对分数排序
print(num_list)
print(list(reversed(num_list))) # 降序输出
【示例3】将部分列表元素反转。
a = [1, '23', 4, 5, 6]
ra = list(reversed(a[:3]))
print(ra) # [4, '23', 1]
a[0:3] = ra
print(a) # [4, '23', 1, 5, 6]
七、sorted()函数——对可迭代对象进行排序
sorted() 函数用于对可迭代对象进行 排序,返回一个重新排序的列表,当使用该函数进行排序后,原列表的元素顺序不变。语法格式如下:
In [14]: sorted?
Signature: sorted(iterable, /, *, key=None, reverse=False)
Docstring:
Return a new list containing all items from the iterable in ascending order.
A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
Type: builtin_function_or_method
参数说明如下:
- iterable:表示可迭代对象,如列表、字符串、字典等。
- key:可选参数,可选参数 key 是一个函数(方法),用来指定排序的规则(即按照指定的方法或函数对可迭代对象进行排序)。例如,设置 key=str.lower,表示可迭代对象中的每个元素转换为小写字母后再进行排序,返回的仍然是可迭代对象中的元素。默认 key=None,表示直接比较元素进行排序。
- reverse:可选参数,排序规则,默认 reverse=False,表示升序排列,如果 reverse=True,则表示降序排列。
- 返回值:返回重新排序的列表。
【示例1】对数字列表进行排序。定义一个保存 10 名学生高考理科成绩在 600 分以上的列表,然后应用 sorted() 函数对其进行升序和降序排列,代码如下:
grade_list = [656, 602, 610, 618, 663, 695, 622, 645, 677, 640] # 10名600分以上的学生成绩列表
# 升序列表: [602, 610, 618, 622, 640, 645, 656, 663, 677, 695]
print(f"升序列表: {sorted(grade_list)}") # 升序排序
# 降序列表: [695, 677, 663, 656, 645, 640, 622, 618, 610, 602]
print(f"降序列表: {sorted(grade_list, reverse=True)}") # 降序排序
【示例2】对字符列表进行排序。定义一个保存字符的列表,然后应用 sorted() 函数对其进行排序,并指定参数 key=str.lower
,代码如下:
char_list = ['a', 'b', 'c', 'd', '*', 'M', 'R', 'S', 'O', 'F', 'T'] # 定义列表
# 默认按字符ASCII码进行排序
# 升序: ['*', 'F', 'M', 'O', 'R', 'S', 'T', 'a', 'b', 'c', 'd']
print(f"升序: {sorted(char_list)}") # 进行升序排列
# 降序: ['d', 'c', 'b', 'a', 'T', 'S', 'R', 'O', 'M', 'F', '*']
print(f"降序: {sorted(char_list, reverse=True)}") # 进行降序排列
# 转换为小写字母后升序: ['*', 'a', 'b', 'c', 'd', 'F', 'M', 'O', 'R', 'S', 'T']
print(f"转换为小写字母后升序: {sorted(char_list, key=str.lower)}")
# 转换为小写字母后升序: ['T', 'S', 'R', 'O', 'M', 'F', 'd', 'c', 'b', 'a', '*']
print(f"转换为小写字母后升序: {sorted(char_list, key=str.lower, reverse=True)}")
* 的 ASCII 值为 41,A 的 ASCII 值为 65,a 的 ASCII 值为 97。
【示例3】按照列表中嵌套元组的指定元素进行排序。依据英语小 A 班学生列表 students 中元组的第 1 个下标值 (年龄) 和 第 2 个下标值 (身高) 进行升序和降序排列,代码如下:
# 定义列表(姓名、年龄、身高)
students = [('Adas', 3, 99), ('Lily', 4, 110), ('Bella', 4, 112), ('Anna', 3, 95)]
s1 = sorted(students, key=lambda x: x[2]) # 按身高进行升序排列
print('按身高升序:', s1)
s2 = sorted(students, key=lambda x: x[2], reverse=True) # 按身高进行降序排列
print('按身高降序:', s2)
s3 = sorted(students, key=lambda x: x[1]) # 按年龄进行升序排列
print('按年龄升序:', s3)
s4 = sorted(students, key=lambda x: x[1], reverse=True) # 按年龄进行降序排列
print('按年龄降序:', s4)
【示例4】将数字按绝对值进行排序。定义一个含有多个正负数的列表,然后应用 sorted() 函数对其进行排序,并指定参数 key=abc,代码如下:
s = [39, 15, -12, 9, -21, 66]
s_positive = sorted(s) # 正常排序
print(s_positive)
s_negative = sorted(s, key=abs) # 按绝对值排序
print(s_negative)
【示例5】将数字和数字字符串进行排序。在一组数据列表中,有时候可能会混入一些为字符串格式的数字,在 Python3 中是不能将字符串与数字进行比较的,而是需要使用 functools模块
中的 cmp_to_key
来指定比较函数是什么。代码如下:
import functools
def compare(x1, x2):
if isinstance(x1, str):
x1 = float(x1)
if isinstance(x2, str):
x2 = float(x2)
return x1 - x2
nums = [3.9, 15, -1.2, 9, -21, 6.6, '-1', '2.4', '-3.3']
nums_sort = sorted(nums, key=functools.cmp_to_key(compare))
# 输出==>[-21, '-3.3', -1.2, '-1', '2.4', 3.9, 6.6, 9, 15]
print(nums_sort)
【示例6】通过 key 的值对字典进行排序。定义一个包含多个字典的列表,然后应用 sorted() 函数对其进行排序,并指定参数 key=lambda x:x[“age”]。代码如下:
age_name = [{"age": 20, "name": "coc"},
{"age": 25, "name": "ctt"},
{"age": 10, "name": "ctc"}]
age_name_sort = sorted(age_name, key=lambda x: x["age"]) # 通过字典中的age进行排序
# [{'age': 10, 'name': 'ctc'}, {'age': 20, 'name': 'coc'}, {'age': 25, 'name': 'ctt'}]
print(age_name_sort)
【示例7】通过字符串的长度来进行排序。定义一个带有多个字符串的列表,然后应用 sorted() 函数对其进行排序,并指定参数 key=len,或者使用 lambda 表达式,代码如下:
chars = ['Sorted', 'is', 'age', 'name', 'is', 'string', 'test']
chars_sort = sorted(chars, key=len)
print(chars_sort) # 输出:['is', 'is', 'age', 'name', 'test', 'Sorted', 'string']
chars_sort_lambda = sorted(chars, key=lambda x: len(x))
print(chars_sort_lambda) # 输出:['is', 'is', 'age', 'name', 'test', 'Sorted', 'string']
【示例8】使用自定义的方法进行排序。在使用 sorted() 函数进行排序的过程中,key 参数除了可以使用内置的函数和匿名函数外,也可使用自定义的方法。如下所示:
def my_sorted_method(word):
number, letter, other = [], [], []
for i in word:
if i.isdigit(): # 判断是否为数字
number.append(i)
elif i.isalpha(): # 判断是否为字母
letter.append(i)
else:
other.append(i)
list_all = sorted(number + letter + other) # 排序并合并
return list_all
x = ['5', 'e', 'c', 'fe', (), '1', 'a']
x_my = sorted(x, key=my_sorted_method)
print(x_my) # [(), '1', '5', 'a', 'c', 'e', 'fe']
【示例9】对类的实例对象进行排序。如果要排序的元素是自定义类,例如使用 Student 类中的 age 参数来排序。代码如下:
class Student(object):
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
s_examples = [
Student('coc', 'A', 15),
Student('dod', 'B', 12),
Student('god', 'A', 12),
Student('cod', 'B', 10), ]
s_examples_sorted = sorted(s_examples, key=lambda t: t.age) # 使用类的age属性进行排序
# [('cod', 'B', 10), ('dod', 'B', 12), ('god', 'A', 12), ('coc', 'A', 15)]
print(s_examples_sorted)
【示例10】使用多个条件排序。在根据类中的某个属性进行排序时,难免会出现相同的元素,此时可以再指定一条属性用于排序。代码如下:
class Student(object):
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
s_examples = [
Student('coc', 'A', 15),
Student('dod', 'B', 12),
Student('god', 'A', 12),
Student('cod', 'B', 10), ]
s_examples_age_grade = sorted(s_examples, key=lambda t: (t.age, t.grade)) # 使用多个条件排序
print(s_examples_age_grade)
【示例11】自定义类的高效排序。对于自定义类,还有一种更高效的方法用于指定 key,引入 operator 模块下的 attrgetter 类,再将排序的元素传入其中。代码如下:
from operator import attrgetter
class Student:
def __init__(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def __repr__(self):
return repr((self.name, self.grade, self.age))
s_examples = [
Student('coc', 'A', 15),
Student('dod', 'B', 12),
Student('god', 'A', 12),
Student('cod', 'B', 10), ]
s_examples_age_grade = sorted(s_examples, key=lambda t: (t.age, t.grade)) # 使用多个条件排序
print(s_examples_age_grade)
s_examples_agttr = sorted(s_examples, key=attrgetter('age', 'grade')) # 使用多个条件排序
print(s_examples_agttr)
【示例12】对 10 名学生 Python 理论成绩进行排序。定义一个保存 10 名学生 Python 理论成绩的列表,然后应用 sorted() 函数对其进行排序,代码如下:
grade = [98, 99, 97, 100, 100, 96, 94, 89, 95, 100] # 10名学生Python理论成绩列表
grade_as = sorted(grade) # 进行升序排列
print('升序:', grade_as)
grade_des = sorted(grade, reverse=True) # 进行降序排列
print('降序:', grade_des)
print('原序列:', grade)
列表对象的 sort() 方法 和 内置 sorted() 函数的作用基本相同,所不同的就是使用 sort() 方法时,会改变原列表的元素排列顺序,而使用 sorted() 函数时,会建立一个原列表的副本,该副本为排序后的列表。
在数据统计过程中,经常会用到中位数。首先了解一下什么是中位数。在数据排序后,位置在最中间的数值就是中位数。当数据样本数为奇数时,中位数就是最中间的数值,如 1、2、3、4、5 这 5 个数,中位数是中间的数字 3,当数据样本数为偶数时,中位数则是中间两个数的平均值,如 1、2、3、4、5、6 这 6 个数,中位数是 3.5。
【示例13】下面通过程序统计某单位员工年龄的中位数。抽取 10 名员工,年龄分别为 23、32、45、20、25、28、30、35、26、41。首先对这组数据进行排序,然后统计年龄的中位数,代码如下:
num = [23, 32, 45, 20, 25, 28, 30, 35, 26, 41] # 一组年龄数据
data = sorted(num) # 排序
n = len(data) # 列表的长度(即数据的个数)
# 通过列表索引获取指定位置的年龄,然后统计年龄的中位数
media = (data[n // 2] + data[n // 2 - 1]) / 2
print("年龄的中位数是: ", media)
【示例14】将包括数字、字符、中文汉字的字符串列表按数值大小排序。如果一个列表中元素为字符串类型的浮点数、整数和带中文标识的数,如 -2、-1.1、-1、1、1.3、1层、2
。现在需要将其按元素中的数值进行排序。排序后的结果为 -2、-1.1、-1、1、1层、1.3、2
。这时可以通过使用 sorted() 函数,并且指定排序关键字实现。代码如下:
import re # 导入正则表达式模块
list1 = ['-2', '-1.1', '-1', '1', '1.3', '1层', '2']
print('未排序:', list1)
list1 = sorted(list1, key=lambda x: (float(re.sub('[\u4e00-\u9fa5]', '', x))))
# 未排序: ['-2', '-1.1', '-1', '1', '1.3', '1层', '2']
print('已排序:', list1)
# 已排序: ['-2', '-1.1', '-1', '1', '1层', '1.3', '2']
在 Python 中,进行中文汉字排序时,默认按汉字的 Unicode 编码进行排序,这种排序结果和我们常见的按拼音顺序排序不一样。通过借助 第三方模块xpinyin
和自定义排序规则可以实现 按拼音顺序排序
中文。具体步骤如下:
(1) 安装第三方模块 xpinyin。在 CMD 命令行窗口中,输入以下安装命令:
(2) 导入 xpinyin 模块,代码如下:
from xpinyin import Pinyin # 导入汉字转拼音模块
(3) 编写自定义函数,作为按中文汉字排序的规则。在该函数中,首先应用第三方模块 xpinyin 的 get_pinyin() 方法获取中文汉字的拼音,并且和对应的汉字放到一个元组中,再添加到列表中,然后对该列表排序,最后遍历排序后的列表,取出汉字保存到新列表中返回。具体代码如下:
from xpinyin import Pinyin # 导入汉字转拼音模块
def my_sort(wordlist): # 指定要排序的列表
pin = Pinyin() # 创建汉字转拼音对象
temp = [] # 保存转换结果的空列表
for item in wordlist: # 遍历品牌名称列表
# 将汉字的拼音和汉字放到一个元组中,再添加到列表中
temp.append((pin.get_pinyin(item), item))
temp.sort() # 对列表进行排序
result = [] # 保存排序后的列表
for i in range(len(temp)): # 遍历排序后的列表
result.append(temp[i][1]) # 取出汉字保存到新列表中
return result # 返回排序后的列表
(4) 定义要排序的列表,并且应用 sorted() 函数按指定的规则进行排序,代码如下:
friend = ['天净沙秋思', '大鱼', 'Aurora', '宁静致远', '丁灵儿', '恒则成']
print('排序前:', friend)
newfriend = sorted(friend, key=lambda i: my_sort(friend).index(i))
print('排序后:', newfriend)
八、zip()函数——将可迭代对象打包成元组
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的 zip 对象。语法格式如下:
In [15]: zip?
Init signature: zip(self, /, *args, **kwargs)
Docstring:
zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.
>>> list(zip('abcdefg', range(3), range(4)))
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
The zip object yields n-length tuples, where n is the number of iterables
passed as positional arguments to zip(). The i-th element in every tuple
comes from the i-th iterable argument to zip(). This continues until the
shortest argument is exhausted.
If strict is true and one of the arguments is exhausted before the others,
raise a ValueError.
Type: type
Subclasses:
参数说明:
*iterables
: 可迭代对象,如列表、字典、元组、字符串等,zip() 函数允许多个可迭代对象作为参数。- 当 zip() 函数没有参数时,则返回空的迭代器。
- 当 zip() 函数只有一个参数时,则从参数中依次取一个元素组成一个元组,再将依次组成的元组组合成一个新的迭代器。
- 当 zip() 函数有两个参数时,分别从两个参数中依次各取出一个元素组成元组,再将依次组成的元组组合成一个新的迭代器。
- 返回值:返回一个可迭代的 zip 对象,其内部元素为元组,可以使用 list() 函数 或 tuple() 函数将其转换为列表或元组。
【示例1】用 zip() 函数实现列表合并。下面使用 zip() 函数实现将两个列表进行合并。例如,将 name_list、age_list 两个列表合并,代码如下:
name_list = ["Amo", "Paul", "Jason", "Seven"]
age_list = [18, 19, 20, 21]
# 输出 ==> [('Amo', 18), ('Paul', 19), ('Jason', 20), ('Seven', 21)]
print(list(zip(name_list, age_list)))
【示例2】使用 zip() 函数建立字典。有两个列表 name_list 和 score_list,其中 name_list 中存储着学生姓名,score_list 存储着每个学生的考试成绩,如果要通过某个学生姓名来查找其考试成绩,则需要一个字典,zip() 函数可以很方便地建立字典,代码如下:
name_list = ["Amo", "Paul", "Jason", "Seven"] # 定义列表name_list
score_list = [80, 96, 77, 88] # 定义成绩
my_dict = dict(zip(name_list, score_list)) # 使用dict()函数将zip对象转换为字典
print(my_dict["Amo"]) # 输出 80
【示例3】zip() 函数妙用 1— 矩阵的旋转。矩阵是高等数学中的常见工具,也常用于统计分析和数学应用中。下面使用 zip() 函数实现一个 xyz 的矩阵的旋转,代码如下:
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
xyz = list(zip(x, y, z))
print(xyz) # 输出 ==> [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
【示例4】函数妙用 2— 矩阵的行列转置。矩阵的转置是矩阵的一种运算,在矩阵的所有运算法则中占有重要地位。例如,把矩阵 A 的行和列互相交换所产生的的矩阵称为 A 的转置矩阵,这一过程称为矩阵的转置。下面实现将 xyz 矩阵进行转置,代码如下:
x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
xyz = list(zip(x, y, z))
print(xyz)
for a, b, c in zip(x, y, z):
print(f"{a},{b},{c}")
【示例5】zip() 函数妙用 3— 将 4×3 矩阵转置成 3×4 矩阵
data1 = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11))
data2 = zip(*data1)
print(type(data2)) # <class 'zip'>
print(tuple(data2)) # 输出 ==> ((0, 3, 6, 9), (1, 4, 7, 10), (2, 5, 8, 11))
【示例6】通过序列的解压执行 zip() 函数的反操作。在某些情况下,我们需要执行相反的操作 — 解压序列。解压操作涉及将压缩后的元素恢复为其原始状态。可以添加 * 运算符到函数调用中。代码如下:
a = (1, 2, 3)
b = (10, 20, 30)
L = list(zip(a, b))
print(f"obj = {L}")
c, d = list(zip(*L)) # 使用*解压序列
print(f"c = {c} \nd = {d}")
if a == c and b == d:
print("两次 zip() 等于啥都没干......")
【示例7】输出字典中值最大所对应的键。在一个字典当中,求值最大所对应的键时,zip() 函数就派上了大用场。代码如下:
data = {"张三": 100, "李四": 20, "王五": 500, "赵六": 12}
obj = zip(data.values(), data.keys())
# 输出:分数最高的学生姓名为: 王五
print(f"分数最高的学生姓名为: {max(obj)[1]}")
九、reduce()函数
reduce把一个函数作用在一个序列 [x1, x2, x3, …]上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算,其效果就是: reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4),语法格式:
In [16]: from functools import reduce
In [17]: reduce?
Docstring:
reduce(function, iterable[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence
or iterable, from left to right, so as to reduce the iterable to a single
value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the iterable in the calculation, and serves as a default when the
iterable is empty.
Type: builtin_function_or_method
【示例】演示reduce函数的用法。
from functools import reduce
# 例子: 对一个序列求和 注意reduce不是python内置的 在functools模块中
print(reduce(lambda a, b: a + b, [1, 3, 5, 7, 9])) # 这里的话其实可以直接使用sum() 25
# 但是如果想把[1, 3, 5, 7, 9]变成13579 高阶函数reduce就可以派上用场了
print(reduce(lambda a, b: a * 10 + b, [1, 3, 5, 7, 9])) # 13579
# 第一次:1*10+3 -->13
# 第二次:13*10+5 -->135
# 第三次:135*10+7 -->1357
# 第四次:1357*10+9 -->13579
# Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:
def prod(num_list2):
return reduce(lambda x, y: x * y, num_list2)
print(prod([3, 5, 7, 9])) # 945
十、iter()函数——用于生成迭代器
iter() 函数用于根据指定的可迭代集合对象或可调用对象来生成一个迭代器。iter() 函数的语法格式如下:
In [10]: iter?
Docstring:
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
Type: builtin_function_or_method
参数说明:
- iterable:可迭代的对象,如列表、元组等
- sentinel:如果指定参数 iterable,则参数 iterable 必须是一个可调用的对象(如函数),此时,iter 创建了一个迭代器对象,每次调用这个迭代器对象的
__next__()
方法时,都会调用 callable; - 返回值:返回一个 iterator(迭代器)对象。
示例:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 21:12
# @Author : AmoXiang
# @File: iter_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 1.将序列转换为迭代器对象
s = iter('mr') # 将字符串创建迭代器对象
print(s)
print(next(s)) # 返回迭代器的下一个元素
print(next(s))
# 根据字典创建迭代器对象
d1 = iter({'Monday': '星期一', 'Tuesday': '星期二', 'Wednesday': '星期三',
'Thursday': '星期四', 'Friday': '星期五', 'Saturday': '星期六', 'Sunday ': '星期日'})
print(d1)
print(next(d1)) # 返回迭代器的下一个元素,遍历字典中的键(key)
print(next(d1))
print(next(d1))
print(next(d1))
print(next(d1))
print(next(d1))
print(next(d1))
# 2.实现累加计数
class add: # 定义类
def __init__(self, _start, _end):
self.start = _start
self.end = _end
def get_next(self):
s = self.start
if self.start < self.end:
self.start += 1
else:
raise StopIteration
return s
# 使用iter()函数创建迭代器并实现函数回调以及设置截止次数
a = add(1, 20)
iterator = iter(a.get_next, 6)
for i in iterator:
print(i)
十一、next()函数——返回迭代器的下一个元素
next() 函数以迭代器为参数,每次调用的时候,返回迭代器中的下一个元素。next() 函数的语法格式如下:
In [12]: next?
Docstring:
next(iterator[, default])
Return the next item from the iterator. If default is given and the iterator
is exhausted, it is returned instead of raising StopIteration.
Type: builtin_function_or_method
- iterator:迭代器;
- default:可选参数,用于设置在没有下一个元素时返回该值,如果不设置,又没有下一个元素则会出现停止迭代 StopIteration 的异常。
- 返回值:返回迭代器中的下一个元素。
示例:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 21:18
# @Author : AmoXiang
# @File: next_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 1.使用next()函数返回迭代器中的下一个元素
s = iter('xw') # 将字符串序列转为迭代器对象
print(next(s)) # 返回迭代器的下一个元素
print(next(s))
# print(next(s)) # 没有下一个元素,出现停止迭代StopIteration异常
s = iter('xw') # 将字符串序列转为迭代器对象
print(next(s, 'x'))
print(next(s, 'x'))
print(next(s, 'x')) # 返回default指定的默认值
print(next(s, 'x'))
# 2.循环推进迭代器元素
l1 = iter(['a', 'b', 'c', 'd', 'e']) # 使用iter()函数创建迭代器
while 1:
try:
print(next(l1)) # 获取下一个值
except StopIteration:
print('停止迭代') # 输出提示
break # 退出循环
# 3.循环推进迭代器元素并设置默认值
list1 = iter([1, 2, 3, 4, 5]) # 创建可迭代对象
while 1:
y = next(list1, 0) # 设置default的值为0
if y: # 条件为真,则输出y的值
print(y)
else: # 否则退出循环
break
十二、enumerate函数–根据可迭代对象创建一个enumerate对象
enumerate() 函数将一个可迭代的对象组合为一个带有数据和数据下标的索引序列,返回一个枚举对象,enumerate() 函数多用在 for 循环中,用于遍历序列中的元素以及它们的下标。其语法格式如下:
In [18]: enumerate?
Init signature: enumerate(iterable, start=0)
Docstring:
Return an enumerate object.
iterable
an object supporting iteration
The enumerate object yields pairs containing a count (from start, which
defaults to zero) and a value yielded by the iterable argument.
enumerate is useful for obtaining an indexed list:
(0, seq[0]), (1, seq[1]), (2, seq[2]), ...
Type: type
Subclasses:
参数说明:
- iterable:一个序列、迭代器或其他支持迭代的对象,如列表、元组、字符串等;
- start:下标的起始值,默认从 0 开始;
- 返回值:返回一个 enumerate(枚举) 对象。
示例:
# -*- coding: utf-8 -*-
# @Time : 2024-09-06 21:36
# @Author : AmoXiang
# @File: enumerate_demo.py
# @Software: PyCharm
# @Blog: https://blog.csdn.net/xw1680
# 1.将enumerate对象转换为列表
num = ('one', 'two', 'three', 'four') # 创建元组数据
print(enumerate(num)) # 返回一个enumerate对象
print(list(enumerate(num))) # 使用list()函数转换为列表,下标的起始值默认从0开始
print(list(enumerate(num, 2))) # 设置下标的起始值从2开始
# 2.通过enumerate()函数合并列表索引
list1 = ['python', 'java', 'asp.net', 'c++', 'vb'] # 创建列表list1
list2 = ['sqlserver', 'oracle', 'mysql', 'mongodb'] # 创建列表list2
en1 = enumerate(list1) # 创建list1列表的enumerate对象
en2 = enumerate(list2, start=5) # 创建list2列表的enumerate对象,下标以5开始
resultList = list(en1) + list(en2) # 将两个enumerate对象转换为列表,并合为一个列表
print('合并后的列表内容为:\n', resultList) # 打印合并后的列表内容
# 3.循环遍历序列中的元素及下标
# 函数多用在for循环中,用于遍历序列中的元素以及它们的下标。使用for循环和enumerate()函数实现同时输出索引值和元素内容的功能
# 其语法格式如下:
# for idx,item in enumerate(iterable):
# 输出idx和item
# 参数说明:
# idx:用于保存元素的索引;
# item:用于保存获取到的元素值,要输出元素内容时,直接输出该变量即可;
# iterable:可迭代对象。
list3 = ['Forever', 'I Need You', 'Alone', 'Hello'] # 列表数据
for idx, item in enumerate(list3): # 循环遍历列表中的元素及下标
print('列表元素下标为:', idx, '列表元素为:', item)