python快速入门学习笔记(进阶篇)十五:函数进阶知识(上)

  • 原创
  • 作者:程序员三丰
  • 发布时间:2026-03-27 10:16
  • 浏览量:19
python入门第十五课,主要是学习了函数的一些进阶知识,比如:多返回值、高阶函数、条件表达式、匿名函数,以及常用数据处理函数map、filter、sorted、reduce等。

重新认识函数

1️⃣ 函数也是对象

# 函数也是对象
a1 = 100    # a1是int类型的实例
a2 = 'hellp'    # a2是str类的实例
a3 = [10, 20, 30]   # a4是list类的实例

# welcome函数是function类的实例对象
def welcome():
    print("你好,Python")

print(type(a1)) # <class 'int'>
print(type(a2)) # <class 'str'>
print(type(a3)) # <class 'list'>
print(type(welcome)) # <class 'function'>

上面代码中 welcome 函数的内存示意图:

2️⃣ 函数可以像对象一样,动态添加属性

def welcome():
    print("你好,Python")

# 动态添加属性
welcome.desc = '这是一个用户打招呼的函数'
welcome.version = '1.0'
print(welcome.__dict__)

# 调用函数
welcome()

上述代码的内存结构示意图:

3️⃣ 函数可以赋值给变量

def welcome():
    print("你好,Python")

# 把函数对象赋值给变量
say_hello = welcome

# 通过变量调用函数
say_hello()

# 通过函数名调用函数
welcome()

上述代码的结构示意图:

4️⃣ 可变参数 vs 不可变参数

不可变参数 代码示例:

def welcome(data):
    print(f'函数收到的data是:{data},地址是:{id(data)}')
    data = 999
    print(f'被修改后的data是:{data},地址是:{id(data)}')

a = 666
print(f'函数外侧a的值是:{a},地址是:{id(a)}')
welcome(a)
print(f'函数调用后a的值是:{a},地址是:{id(a)}')

可变参数 代码示例:

def welcome2(data):
    print(f'函数收到的data是:{data},地址是:{id(data)}')
    data[2] = 999
    print(f'被修改后的data是:{data},地址是:{id(data)}')

a = [10, 20, 30]
print(f'函数外侧a的值是:{a},地址是:{id(a)}')
welcome2(a)
print(f'函数调用后a的值是:{a},地址是:{id(a)}')

5️⃣ 函数也可以作为参数

def welcome():
    print("你好,Python")

def caller(func):
    print('caller函数开始调用')
    func()

caller(welcome)

6️⃣ 函数也可以作为返回值

def welcome():
    print('你好啊')
    def show_message():
        print('你好python')
    return show_message


result = welcome()
result()

# 换种写法
welcome()()

函数的多返回值

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

def calculate(x, y):
    res1 = x + y
    res2 = x - y
    return res1, res2 # 实际返回的结果是:(res1, res2)

result = calculate(1, 2)
print(result, type(result)) # (3, -1) <class 'tuple'>
r1, r2 = calculate(1, 2) # 直接解包
print(r1, r2) # 3 -1

参数的打包与解包

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

  • *形参名:打包所有的位置参数,形成一个元组。
  • **形参名:打包所有的关键字参数,形成一个字典。

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

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

示例代码:

def show_info(*args, **kwargs):
    print(type(args), args) # <class 'tuple'> (10, 20, 30)
    print(type(kwargs), kwargs) # <class 'dict'> {'name': '张三', 'age': 41}


nums = (10, 20, 30)
person = {'name': '张三', 'age': 41}
show_info(*nums, **person)

高阶函数

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

示例代码:

def welcome():
    print("你好啊")

# 函数作为参数
def caller(f):
    print('caller函数开始调用')
    f()

caller(welcome)

# 函数作为返回值
def outer():
    print('我是outer')
    def inner():
        print('inner')
    return inner

outer()()

高阶函数意义:

❏ 代码复用性高:可以把行为“独立出去”,传入不同函数实现不同逻辑。

❏ 能让函数更灵活,更通用。

❏ 高阶函数是:装饰器、闭包的基础。(后续文章详解)

高阶函数的一个小应用:

def info(msg):
    return '【提示】' + msg
def warn(msg):
    return '【警告】' + msg
def error(msg):
    return '【错误】' + msg

def log(func, text):
    print(func(text))

log(info, '文件保存成功!')
log(warn, '磁盘空间不足!')
log(error, '该用户不存在!')

条件表达式

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

3 + 5
'abc' * 3
5 > 3
'y' in 'python'
len('hello')

条件表单式:根据不同的条件得到不同的值,又称:三元运算符 或 三目运算符。语法格式如下:

结果1 if 条件 else 结果2

语义解释:如果条件为真,整个表达式的结果就是“结果1”,否则就是“结果2”。

示例代码:

age = 20

# if-else的写法
if age >= 18:
    text = '成年'
else:
    text = '未成年'
print(text)

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

匿名函数

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

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

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

下面的示例代码展示同样的功能,分别使用普通函数与匿名函数实现:

  • 普通函数实现
def add(a, b):
    return a + b

def sub(a, b):
    return a - b

def calculate(func, a, b):
    print(f'计算结果为:{func(a, b)}')

calculate(add, 2, 3)
calculate(sub, 2, 3)
  • 匿名函数实现
def calculate(func, a, b):
    print(f'计算结果为:{func(a, b)}')

# 使用匿名函数
calculate(lambda a, b: a + b, 1, 2)
calculate(lambda a, b: a - b, 1, 2)

特点:

  • 只能写一行,不能写多行代码。
  • 不能写代码块(if、for、while)。
  • 冒号右边必须是表达式,且只能写一个返回值。
  • 执行结果自动作为返回值。

示例代码(匿名函数 + 条件表达式):

is_adult = lambda age: '成年' if age >= 18 else '未成年'
print(is_adult(18))
print(is_adult(13))

几个常用数据处理函数

map函数

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

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

注意点:

  • map函数返回的是一个迭代器对象,需要我们去手动遍历,或者手动转换类型。
  • 返回的是迭代器对象,且一旦遍历完成,就会被“耗尽”。
  • 延迟执行:map 不会立刻计算,只有在“需要结果”时才执行计算。
  • map 不会影响元素数量。

示例代码:

# 统一数据处理
nums1 = [10, 20, 30, 40]
result = map(lambda x: x * 2, nums1)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(list(result)) # [20, 40, 60, 80]
print(nums1) # [10, 20, 30, 40]

# 字符串格式化
names = ('python', 'java', 'ts')
result = map(lambda x: x.upper(), names)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(tuple(result)) # ('PYTHON', 'JAVA', 'TS')
print(list(result)) # [] ??为什么为空呢?原因是迭代器对象上一行代码已经遍历过了,就会“耗尽”了
print(names) # ('python', 'java', 'ts')

# 类型转换
str_num = {'1', '2', '3', '4'}
result = map(int, str_num)
print(type(result), result) # 返回迭代器对象 <class 'map'> <map object at 0x000001C58AFBB880>
print(set(result)) # {1, 2, 3, 4}
print(str_num) # {'1', '2', '3', '4'}

# 验证:map返回的迭代器对象,一旦遍历完成,就会被“耗尽”
num2 = [10, 20, 30]
result = map(lambda x: x * 3, num2)
print(type(result), result)
print(list(result))
print(list(result))
print(list(result))
print(num2)

filter函数

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

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

注意点:

  • 延迟执行:filter 不会立刻筛选,只有在“需要结果”时才执行。
  • 返回迭代器对象,一旦遍历完成就会被“耗尽”。
  • 如果不传递过滤函数,那么会自动过滤掉“假值”。

示例代码:

# 筛选数值
nums = [10, 20, 30, 40, 50]
result = filter(lambda n: n > 20, nums)
print(type(result), result)  # <class 'filter'> <filter object at 0x0000020D5A43BA00>
print(list(result))  # [30, 40, 50]
print(list(result))  # []
print(nums)  # [10, 20, 30, 40, 50]

# 筛选成年人
persons = [
    {'name': '张三', 'age': 15, 'gender': '男'},
    {'name': '李四', 'age': 16, 'gender': '女'},
    {'name': '王五', 'age': 21, 'gender': '男'},
    {'name': '李华', 'age': 18, 'gender': '女'},
    {'name': '赵六', 'age': 19, 'gender': '女'},
    {'name': '孙琪', 'age': 20, 'gender': '男'},
]
result = filter(lambda p: p['age'] > 19, persons)
print(type(result), result)  # <class 'filter'> <filter object at 0x000001C71B0DCA00>
print(list(result))  # [{'name': '王五', 'age': 21, 'gender': '男'}, {'name': '孙琪', 'age': 20, 'gender': '男'}]
print(list(result))  # []

# 过滤非法字符串
names = ['张三', '', '李四', None, '王五']
result = filter(lambda n: n, names)
print(type(result), result)  # <class 'filter'> <filter object at 0x000001BDC7BACDC0>
print(list(result))  # ['张三', '李四', '王五']
print(list(result))  # []

# 如果不传递过滤函数,那么自动会过滤掉“假值”
data = [0, 1, '', 'hello', [], (), 5]
result = filter(None, data)
print(type(result), result) # <class 'filter'> <filter object at 0x00000187AB71D0F0>
print(list(result))  # [1, 'hello', 5]

sorted函数

sorted函数:对一组数据进行排序,返回一组新数据。注意该函数返回值是列表类型。

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

# 数字排序
nums = tuple([40, 60, 30, 50])
print(type(nums), nums)  # <class 'tuple'> (40, 60, 30, 50)
result = sorted(nums)
print(type(result), result)  # <class 'list'> [30, 40, 50, 60]
print(sorted(nums, reverse=True))  # [60, 50, 40, 30]

# 按照字符串长度排序
names = ['python', 'sql', 'java']
result = sorted(names, key=len, reverse=False)
print(type(result), result)  # <class 'list'> ['sql', 'java', 'python']

# 根据字典中的某个字段进行排序
persons = [
    {'name': '张三', 'age': 15, 'gender': '男'},
    {'name': '李四', 'age': 16, 'gender': '女'},
    {'name': '王五', 'age': 21, 'gender': '男'},
    {'name': '李华', 'age': 18, 'gender': '女'},
    {'name': '赵六', 'age': 19, 'gender': '女'},
    {'name': '孙琪', 'age': 20, 'gender': '男'},
]
result = sorted(persons, key=lambda p: p['age'], reverse=True)
print(type(result),
      result)  # <class 'list'> [{'name': '王五', 'age': 21, 'gender': '男'}, {'name': '孙琪', 'age': 20, 'gender': '男'}, {'name': '赵六', 'age': 19, 'gender': '女'}, {'name': '李华', 'age': 18, 'gender': '女'}, {'name': '李四', 'age': 16, 'gender': '女'}, {'name': '张三', 'age': 15, 'gender': '男'}]

拓展:我们之前学过的max函数,min函数,也可以传递key参数,用于设置筛选依据。

persons = [
    {'name': '张三', 'age': 15, 'gender': '男'},
    {'name': '李四', 'age': 16, 'gender': '女'},
    {'name': '王五', 'age': 21, 'gender': '男'},
    {'name': '李华', 'age': 18, 'gender': '女'},
    {'name': '赵六', 'age': 19, 'gender': '女'},
    {'name': '孙琪', 'age': 20, 'gender': '男'},
]

result = max(persons, key=lambda p: p['age'])
print(type(result), result) # <class 'dict'> {'name': '王五', 'age': 21, 'gender': '男'}
result = min(persons, key=lambda p: p['age'])
print(type(result), result) # <class 'dict'> {'name': '张三', 'age': 15, 'gender': '男'}

reduce函数

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

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

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

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

# 数值统计
nums = [1, 2, 3, 4, 5]
result = reduce(lambda a, b: a + b, nums)
print(type(result), result)  # <class 'int'> 15
result = reduce(lambda a, b: a + b, nums, 100)
print(type(result), result)  # <class 'int'> 115

# 拼接字符串
str_list = ['ab', 'cd', 'ef']
result = reduce(lambda a, b: a + b, str_list)
print(type(result), result) # <class 'str'> abcdef
result = reduce(lambda a, b: a + b, str_list, '**')
print(type(result), result) # <class 'str'> **abcdef
声明:本文为原创文章,51blog.xyz和作者拥有版权,如需转载,请注明来源于51blog.xyz并保留原文链接:https://mp.51blog.xyz/article/116.html

文章归档

推荐文章

buildadmin logo
Thinkphp8 Vue3 Element PLus TypeScript Vite Pinia

🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。

热门标签

PHP ThinkPHP ThinkPHP5.1 Go Mysql Mysql5.7 Redis Linux CentOS7 Git HTML CSS CSS3 Javascript JQuery Vue LayUI VMware Uniapp 微信小程序 docker wiki Confluence7 学习笔记 uView ES6 Ant Design Pro of Vue React ThinkPHP6.0 chrome 扩展 翻译工具 Nuxt SSR 服务端渲染 scrollreveal.js ThinkPHP8.0 Mac webman 跨域CORS vscode GitHub ECharts Canvas vue3 three.js 微信支付 PHP全栈开发 Python AI 人工智能 AI生成 工作经验 实战笔记