当前位置:首页>python>Python之高阶函数

Python之高阶函数

  • 2026-08-22 11:09:27
Python之高阶函数

第六章 函数进阶

1. 从头认识函数

之前Python之函数入门已经对函数有了初步的介绍,此章我们探讨函数的高阶部分。

  • 函数也是对象
# 1.函数也是对象
x1 = 999# int类的实例对象
x2 = 'Python'# str类的实例对象
x3 = [11, 22, 33] # list类的实例对象

defmessage():# message函数是function类的实例对象
    print('Python')

print(type(x1)) # <class 'int'>
print(type(x2)) # <class 'str'>
print(type(x3)) # <class 'list'>
print(type(message())) # <class 'function'>
  • 函数可以动态的添加属性
# 2.函数可以动态添加属性
defmessage():
    print('Python')
message.desc = '这是一个Python信息'
message.version = 1.0
print(message.desc)  # 这是一个Python信息
print(message.version) # 1.0
  • 函数可以赋值给变量
# 3.函数可以赋值给变量
defmessage():
    print('Python')
message.desc = 'Hello Python'
message.version = 1.0

say_hello = message
say_hello() # Python
print(say_hello.desc) # Hello Python
print(say_hello.version) # 1.0
  • 可变参数与不可变参数(重点)
# 4.可变参数 vs 不可变参数
# 不可变参数
a = 666
defwelcome(data):
    print('data修改前:', data, '对象地址:', id(data))
    data = 888
    print('data修改后:', data, '对象地址:', id(data))

print('函数调用前:', a, '对象地址:', id(a)) 
welcome(a)
print('函数调用后:', a, '对象地址:', id(a)) 

# 执行结果顺序:
# 函数调用前: 666 对象地址: 1532474442064
# data修改前: 666 对象地址: 1532474442064
# data修改后: 888 对象地址: 1532474442032
# 函数调用后: 666 对象地址: 1532474442064

# 可变参数
a = [10, 20, 30]
defwelcome(data):
    print('data修改前:', data, '对象地址:', id(data))
    data[2] = 99
    print('data修改后:', data, '对象地址:', id(data))

print('函数调用前:', a, '对象地址:', id(a))
welcome(a)
print('函数调用后:', a, '对象地址:', id(a))

# 执行结果顺序:
# 函数调用前: [10, 20, 30] 对象地址: 1532472185216
# data修改前: [10, 20, 30] 对象地址: 1532472185216
# data修改后: [10, 20, 99] 对象地址: 1532472185216
# 函数调用后: [10, 20, 99] 对象地址: 1532472185216
  • 函数也可以作为参数
# 5.函数也可以作为参数
defmessage():
    print("Hello Python")

defcall(fun):
    print("call函数被调用了")
    fun()
call(message)
# 执行结果:
# call函数被调用了
# Hello Python
  • 函数也可以作为返回值
# 6.函数也可以作为返回值
defmessage():
    print("Hello")
defview_msg(msg):
        print(msg)
return view_msg

result = message()
result("Python")
message()('Python')
# 执行结果:
# Hello
# Python
# Hello
# Python

2. 函数的多返回值

在return关键字后面写多个值,并且多个值之间用逗号隔开,Python会自动把多个值打包成一个元组。

# 一.函数的多返回值
defcalculate(num1, num2):
    result1 = num1 + num2
    result2 = num1 - num2
return result1, result2
result = calculate(10, 5)
print(result) # (15, 5)
res1, res2 = calculate(10, 5)
print(res1, res2) # 15 5

3. 参数的打包与解包

定义函数时,打包接收参数:

  • *形参名:打包所有的位置参数(会形成一个元组)。
  • **形参名:打包所有的位置参数(会形成一个字典)。

调用函数时,解包传递参数:

  • *变量名:将元组拆解成一个一个独立的位置参数。
  • **变量名:将字典拆解成一个一个key = value形式的关键字参数。
# 二.参数的打包和解包

# 1.打包接收参数:
# *args    :打包所有的位置参数(会形成一个元组)
# **kwargs :打包所有的关键字参数(会形成一个字典)
defview_info(*args, **kwargs):
    print(args) # (10, 20, 30)
    print(kwargs) # {'name': '张三丰', 'age': 99, 'gender': '神仙'}
view_info(10, 20, 30, name='张三丰', age=99, gender='神仙')

# 2.解包传递参数
# *变量名  :将元组拆解成一个一个独立的位置参数
# **变量名 :将字典拆解一个一个 key=value 形式的关键字参数
defshow_info(num1, num2, num3, name, age, gender):
    print(num1, num2, num3) # 10 20 30
    print(name, age, gender) # 张三丰 99 神仙
nums = (10, 20, 30)
person = {'name':'张三丰', 'age':99, 'gender':'神仙'}
show_info(*nums, **person)

# 3.打包接收参数和解包传递参数一起使用
defshow_info(*args, **kwargs):
    print(args) # (10, 20, 30)
    print(kwargs) # {'name': '张三丰', 'age': 99, 'gender': '神仙'}
nums = (10, 20, 30)
person = {'name':'张三丰', 'age':99, 'gender':'神仙'}
show_info(*nums, **person)

4. 高阶函数

当一个函数的参数是函数或者返回值是函数,那么该函数就是高阶函数。

# 高阶函数:当一个函数的『参数是函数』或者『返回值是函数』那该函数就是『高阶函数』。
# 高阶函数的意义:
# 1.代码的复用性高:可以把行为“独立出去”,传入不同函数实现不同的逻辑。
# 2.能让函数更灵活,更通用。
# 3.高阶函数是:装饰器,闭包的基础。
definfo(msg):
return'【提示】:' + msg

defwarning(msg):
return'【警告】:' + msg

deferror(msg):
return'【错误】:' + msg

deflog(fun, text):
    print(fun(text))

log(info, '文件保存成功!') # 【提示】:文件保存成功!
log(warning, '磁盘空间不足!') # 【警告】:磁盘空间不足!
log(error, '该用户不存在!') # 【错误】:该用户不存在!

5. 条件表达式

表达式:执行后最终能得到一个值的代码,就是表达式,例如一下都是表达式。

# 表达式:执行后能得到值的代码,就是表达式(表达式最终会形成一个值,可以写在任何需要值的地方)。
# a1 = 3 + 5
# a2 = 'abc' * 3
# print(5 > 3)
# int('y' in 'python')
# a5 = len('hello')

条件表达式:根据不同的条件,得到不同的值,又称:三元表达式,三目原算法。

具体规则:如果条件为真,整个表达式的结果就是结果1,否则就是结果2。

# 语法格式:
结果1if 条件 else 结果2
# 条件表达式:根据条件的真假,在两个值中二选一的表达式。(又称:三元表达式,三元运算符)。
age = 18
# 传统的if-else写法:
if age >= 18:
    text = '成年'
else:
    text = '未成年'
print(text) # 成年

# 条件表达式写法:值1 if 条件 else 值2
text = '成年'if age >= 18else'未成年'
print(text) # 成年

# 条件表达式的使用场景:简单的二选一场景
rain = True
eat = '外卖'if rain else'出去吃'

is_vip = False
disscount = 0.8if is_vip else1.0

is_login = False
msg = 'Hello'if is_login else'Python'

print(eat) # 外卖
print(disscount) # 1.0
print(msg) # Python

6. 匿名函数

概念:所谓匿名函数,就是没有名字的函数,它无需使用def关键字去定义。

语法:Python中使用lambda关键字来定义匿名函数,格式为:lambda 参数: 表达式。

使用场景:当一个函数只用一次,只做一点点小事,使用匿名函数会更简洁。

# 使用普通函数实现计算效果
defadd(a, b):
return a + b

defsub(a, b):
return a - b

defcalculate(fun, a, b):
    print(f'计算结果为:{fun(a, b)}')

calculate(add, 6, 5) # 计算结果为:11
calculate(sub, 6, 5) # 计算结果为:1

# 匿名函数
add1 = lambda a, b: a + b
add2 = lambda a: a + a
add3 = lambda : '我是add3函数'

result1 = add1(10, 20)
result2 = add2(30)
result3 = add3()
print(result1) # 30
print(result2) # 60
print(result3) # 我是add3函数

# 使用匿名函数实现计算效果
defcalculate(fun, a, b):
    print(f'计算结果为:{fun(a, b)}')
calculate(lambda a, b: a + b, 10, 20) # 计算结果为:30
calculate(lambda a, b: a - b, 10, 20) # 计算结果为:-10

匿名函数注意点:

  1. 只能写一行,不能写多行代码。
  2. 不能写代码块(if,for,while)。
  3. 冒号右边必须是表达式,且只能写一个表达式。
  4. 表达式结果自动作为返回值。
# 匿名函数注意点:
# 1.只能写一行,不能写多行代码。
# 2.不能写代码块(if,for,while)
# 3.冒号右边必须是表达式,且只能写一个表达式。
# 4.表达式结果自动作为返回值。
is_adult = lambda age: '成年'if age >= 18else'未成年'
print(is_adult(18)) # 成年
print(is_adult(16)) # 未成年

7. 数据处理函数

7.1 map函数

map函数:对一组数据中的每一个元素,统一执行某种操作(加工),并生成一组新数据。

语法格式:map(操作函数,可迭代对象)。

# 统一数据处理
nums = [10, 20, 30, 40, 50]
# map函数的返回值是一个迭代器对象,需要我们自己去手动遍历,或者手动类型转换。
result = map(lambda x: x * 2, nums)
print(list(result)) # [20, 40, 60, 80, 100]
print(nums) # [10, 20, 30, 40, 50]

# 字符串转换
bookName = ('Python', 'java', 'vue')
result = map(lambda x: x.upper(), bookName)
print(tuple(result)) # ('PYTHON', 'JAVA', 'VUE')
print(bookName) # ('Python', 'java', 'vue')

# 类型转换
str_num = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}
result = map(int, str_num)
print(set(result)) # {1, 2, 3, 4, 5, 6, 7, 8, 9}
print(str_num) # {'3', '9', '1', '4', '7', '2', '5', '8', '6'}

map函数注意点:

  1. 延迟执行:map不会立刻计算,只有在"需要结果"时才会执行计算。

  2. 返回的是迭代器对象,且一旦遍历完成,就会被"耗尽"。

  3. map不会影响元素数量。

nums = [10, 20, 30, 40, 50]
result = list(map(lambda x: x * 2, nums))
print(result) # [20, 40, 60, 80, 100]
print(result) # [20, 40, 60, 80, 100]
print(result) # [20, 40, 60, 80, 100]

7.2 filter函数

filter函数:从一组数据中,筛选出符合条件的元素(过滤),并组成一组新数据。

语法格式:filter(过滤函数,可迭代对象)

# 筛选数值
nums = [10, 20, 30, 40, 50]
result = filter(lambda num: num > 30, nums)
print(list(result)) # [40, 50]
print(nums) # [10, 20, 30, 40, 50]

# 筛选成年人
persons = [
    {'name':'唐僧', 'age':100, 'gender':'男'},
    {'name':'孙悟空', 'age':999, 'gender':'男'},
    {'name':'猪八戒', 'age':888, 'gender':'男'},
    {'name':'沙和尚', 'age':777, 'gender':'男'},
    {'name':"白龙马", 'age':666, 'gender':'男'},
    {'name':'白骨精', 'age':555, 'gender':'女'},
]
result = filter(lambda per: per['age'] >= 999, persons)
print(list(result)) # [{'name': '孙悟空', 'age': 999, 'gender': '男'}]

# 过滤一下非法字符串
names = ['唐僧', '', '猪八戒', '沙和尚', 'None']
result = filter(lambda n: n, names)
print(list(result)) # ['唐僧', '猪八戒', '沙和尚', 'None']

# filter注意点:
# 1.延迟执行:filter不会立刻筛选,只有在"需要结果"时才会执行。
# 2.返回的是迭代器对象,且一旦遍历完成就会被耗尽。
# 3.filter可能会影响元素数量。

# filter函数的特殊用法,如果不传递过滤函数,那么自动回过滤掉"假值"。
data = [0, 1, '', 'hello', [], (), 5]
result = filter(None, data)
print(list(result)) # [1, 'hello', 5]

7.3 sorted函数

sorted函数:对一组数据进行排序,返回一组新数据。

语法格式:sorted(可迭代对象, key=xxx, reverse=xxx)

# 数字排序
nums = [1, 2, 3, 4, 5, 6]
result = sorted(nums, reverse=True)
print(result) # [6, 5, 4, 3, 2, 1]

# 按照字符串的长度去排序
names = ['Sql', 'Python', 'Java', 'Vue']
result = sorted(names, key=len, reverse=True)
print(result) # ['Python', 'Java', 'Sql', 'Vue']

# 根据字典中的某个字段进行排序
persons = [
    {'name':'唐僧', 'age':100, 'gender':'男'},
    {'name':'孙悟空', 'age':999, 'gender':'男'},
    {'name':'猪八戒', 'age':888, 'gender':'男'},
    {'name':'沙和尚', 'age':777, 'gender':'男'},
    {'name':"白龙马", 'age':666, 'gender':'男'},
    {'name':'白骨精', 'age':555, 'gender':'女'},
]
result = sorted(persons, key=lambda p: p['age'], reverse=True)
print(result) #
# 执行结果:
# [{'name': '孙悟空', 'age': 999, 'gender': '男'},
# {'name': '猪八戒', 'age': 888, 'gender': '男'},
# {'name': '沙和尚', 'age': 777, 'gender': '男'},
# {'name': '白龙马', 'age': 666, 'gender': '男'},
# {'name': '白骨精', 'age': 555, 'gender': '女'},
# {'name': '唐僧', 'age': 100, 'gender': '男'}]

# 我们之前将的max函数,min函数,也可以传递key参数,用于设置筛选依据
result1 = max(persons, key=lambda p: p['age'])
result2 = min(persons, key=lambda p: p['age'])
print(result1) # {'name': '孙悟空', 'age': 999, 'gender': '男'}
print(result2) # {'name': '唐僧', 'age': 100, 'gender': '男'}

7.4 reduce函数

reduce函数:将一组数据不断合并,最终归并成一个结果。

语法格式:reduce(合并函数, 可迭代对象, 初始值)

备注:reduce函数需要从functools模块中引入才能使用。

# reduce函数:将一组数据不断“合并”,最终归并成一个结果。
# 语法格式:reduce(合并函数, 可迭代对象, 初始值)。
# 备注:reduce函数需要从 functools 模块中引入才能使用。

# 从functools模块中引入reduce
from functools import reduce

# 数值统计
nums = [1, 2, 3, 4, 5, 6]
result = reduce(lambda x, y: x + y, nums, 10)
print(result) # 31

# 字符串拼接
str_list = ['p', 'y', 't', 'h', 'o', 'n']
result = reduce(lambda x, y: x + y, str_list)
print(result) # python

8. 列表推导式

概念:用一条简洁的语句,从可迭代对象中,生成新猎德语法结构。

语法格式:[表达式 for 变量 in 可迭代对象]

# 列表推导式:用一条简洁语句,从可迭代对象中,生成新列表的语法结构。
# 备注:列表推导式本质上是对 for循环 + append() 的一种简写形式。
# 语法格式:[表达式 for 变量 in 可迭代对象]

# 需求:让列表中每个元素,都变为原来的2倍,得到是一个新的列表
# 方式一:用map函数
nums = [10, 20, 30, 40, 50]
result = list(map(lambda x: x * 2, nums))
print(result) # [20, 40, 60, 80, 100]

# 方式二:用for循环 + append()
nums = [10, 20, 30, 40, 50]
result = []
for n in nums:
    result.append(n * 2)
print(result) # [20, 40, 60, 80, 100]

# 方式三:用列表推导式
nums = [10, 20, 30, 40, 50]
result = [n * 2for n in nums]
print(result) # [20, 40, 60, 80, 100]

# 带条件的列表推导式
nums = [10, 20, 30, 40, 50]
result = [n * 2for n in nums if n > 20]
print(result) # [60, 80, 100]

# 字典推导式
names = ['唐僧', '孙悟空', '猪八戒', '沙和尚']
scores = [10, 20, 30, 40]
result = {names[i]: scores[i] for i in range(len(names))}
print(result) # {'唐僧': 10, '孙悟空': 20, '猪八戒': 30, '沙和尚': 40}

# 集合推导式
names = ['唐僧', '孙悟空', '猪八戒', '沙和尚']
result = {n + '!'for n in names}
print(result) # {'猪八戒!', '唐僧!', '沙和尚!', '孙悟空!'}

names = ['唐僧', '孙悟空', '猪八戒', '沙和尚']
# Python中没有元组推导式,下面这种写法叫:生成器。
result = {n + '!'for n in names}
print(result) # {'猪八戒!', '唐僧!', '沙和尚!', '孙悟空!'}

9. 常用内置函数梳理

一下函数his截止目前,我们需要掌握的一些常用函数。下面的并不是所有,后面还会学习更多的内置函数。

  • 输入与输出
内置函数
含义
print
输出指定内容
objects
要输出的内容
sep
输出多个内容是的分隔符
end
结尾追加的内容
file
输出位置(默认控制台)
flush
是否立即刷新输出
input()
获取用户输入
# 一、输入与输出
# print() ===> 输出指定内容
# 完整参数:print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
# 参数详解:
#   1.objects:要输出的内容
#   2.sep:分隔符
#   3.end:结束符
#   4.file:输出位置
#   5.flush:是否立即刷新

f = open('a.txt', 'w', encoding='utf-8')
print(10, 20, 30, 40, sep='-', end='!', file=f)

import time
# 第一种进度条
print('加载中', end='')
for index in range(5):
    print('.', end='', flush=True)
    time.sleep(1)
print('完成!', end='')

# 第二种进度条
for index in range(1, 101):
    print(f'\r已加载{index}%', end='', flush=True)
    time.sleep(0.1)
  • 类型转换
内置函数
含义
int()
转为整数
float()
转为浮点数
str()
转为字符串
bool()
转为布尔值
list()
转为列表
tuple()
转为元组
set()
转为集合
dict()
转为字典
  • 数字相关
内置函数
含义
abs()
取绝对值
round()
银行家舍入法:小于5舍,大于5入,等于5看前面数字的奇偶(奇入偶舍)
pow(a, b)
计算a的b次方
pow(a, b, c)
计算a的b次方后,在对c取值
divmod(a, b)
返回(商,余数)
max()
最大值(支持key)
min()
最小值(支持key)
sum()
求和
map()
加工一组数据
filter()
按条件过滤数据
reduce()
合并计算(需functool.reduce)
sorted()
排序(支持key)
# 三、数学相关
# abs() =========> 取绝对值
print(abs(-9)) # 9
print(abs(-2.5)) # 2.5
print(abs(3 - 5)) # 2


# round() =======> 四舍五入
# 注意:round函数的四舍五入,是银行家舍入法:小于5就舍,大于5就入,等于5看奇偶(奇入偶舍)
print(round(3.4)) # 3
print(round(4.6)) # 5
print(round(6.5)) # 6
print(round(7.5)) # 8
print(round(7.543, 2)) # 7.54

# pow() =========> 次方
print(pow(2, 3))    # 8  # 2的3次方
print(pow(2, -1))   # 0.5 # 2的-1次方
print(pow(2, 0.5))  # 1.4142135623730951 # 2的开平方
print(pow(2, 3, 5)) # 3 # 2的3次方对5取模


# divmod() ======> 商和余数
print(divmod(10, 3)) # (3, 1)
  • 数据容器相关
内置函数
含义
len()
获取容器中元素个数
range()
生成数字序列(常用与循环)
enumerate()
未序列添加索引
zip()
将多个序列一一配对
# 四、数据容器相关
# len() ==========> 获取容器中元素的个数
# range() ========> 生成一个数字序列(可用于循环)
for index in range(0, 10, 2):
    print(index)

# enumerate() ====> 给序列添加索引
# zip() ==========> 将多个序列一一配对
names = ('张三', '李四', '王五')
scores = [60, 70, 80]
result = zip(names, scores)
for item in result:
    print(item)
  • 类型判断与对象相关
内置函数
含义
type()
查看对象类型
isinstance(obj, type)
判断对象是否属于某个类型
issubclass(A, B)
判断类A是否为类B的子类
id()
查看对象的内存地址
  • 逻辑判断相关
内置函数
含义
all()
所有元素为真时返回True
any()
至少一个为真返回True
# 六、逻辑判断相关
# all() ====> 全为真返回True
l1 = [10, 'Python', {1, 2, 3}, -9]
print(all(l1)) # True

# any() ====> 有一个为真即可
l2 = [0, '', None, False, 10]
print(any(l2)) # True
  • 字符串辅助相关
内置函数
含义
ord()
获取字符的Unicode编码值
chr()
将Unicode编码值转换为字符

ps:橱窗有Python书籍,有需要的道友自行购买,让洒家赚一丢丢佣金吧

最新文章

随机文章