AI项目博客
记录 AI 工程实践与大模型应用

Python 学习笔记 18|重新认识函数

1. 重新认识函数

1️⃣函数也是对象。

a1 = 100            # a1是int类的实例对象
a2 = 'hello'        # a2是str类的实例对象
a3 = [10, 20, 30]   # a3是list类的实例对象

# welcome函数是function类的实例对象
def welcome():
    print('你好啊')

print(type(a1))
print(type(a2))
print(type(a3))
print(type(welcome))

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

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

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

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

# 调用函数
welcome()

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

def welcome():
    print('你好啊!')

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

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

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

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

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

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

a = 666
print(f'函数外侧a的值是:{a},地址是:{id(a)}')
welcome(a)
print(f'函数调用后a的值是:{a},地址是:{id(a)}')
def welcome(data):
    print(f'函数收到的data是:{data},地址是:{id(data)}')
    data[2] = 99
    print(f'被修改后的data是:{data},地址是:{id(data)}')

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

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

def welcome():
    print('你好啊!')

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

caller(welcome)

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

def welcome():
    print('你好啊')
    def show_msg(msg):
        print(msg)
    return show_msg

# result = welcome()
# result('')
welcome()('')

2. 函数的多返回值

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

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

result = calculate(10, 20)
r1, r2 = calculate(10, 20)

print(result)  # (30, -10)
print(r1)      # 30
print(r2)      # -10

3. 参数的打包与解包

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

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

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

  • *变量名:将元组拆解成一个一个独立的位置参数。
  • **变量名:将字典拆解一个一个key=value形式的关键字参数。
# 打包接收参数:
# *args    :打包所有的位置参数(会形成一个元组)
# **kwargs :打包所有的关键字参数(会形成一个字典)
def show_info(*args, **kwargs):
    print(args)
    print(kwargs)

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

# 解包传递参数:
# *nums    :将元组拆解成一个一个独立的位置参数
# **person :将字典拆解一个一个 key=value 形式的关键字参数
show_info(*nums, **person)

4. 高阶函数

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

def welcome():
    print('你好啊!')

# caller函数的参数是函数,所以caller是高阶函数
def caller(f):
    print('call函数开始调用')
    f()

caller(welcome)

# outer函数的返回值是函数,所以outer函数是高阶函数
def outer():
    print('我是outer')
    def inner():
        print('我是inner')
    return inner

高阶函数的意义:

  • 代码复用性高:可以把行为“独立出去”,传入不同函数实现不同逻辑。
  • 能让函数更灵活,更通用。
  • 高阶函数是:装饰器、闭包的基础。(后面会讲)
def info(msg):
    return '[提示]' + msg
def warn(msg):
    return '[警告]' + msg
def error(msg):
    return '[错误]' + msg

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

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

5. 条件表达式

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

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

表达式最终会形成一个值,可以写在任何一个需要值的地方。

条件表达式: 根据不同的条件,得到不同的值,又称:三元表达式,也叫:三目运算符。

1️⃣语法格式为:

结果1 if 条件 else 结果2

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

2️⃣代码示例:

age = 20

# 传统if-else写法
if age >= 18:
    text = '成年'
else:
    text = '未成年'

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

3️⃣ 什么时候适合用条件表达式? —— 简单的二选一场景,可以让代码更紧凑。

rain = True
food = '外卖' if rain else '出去吃'

is_vip = True
disscount = 0.8 if is_vip else 1.0

is_login = True
msg = '欢迎回来!' if is_login else '请先登录!'

6. 匿名函数

  • 概念:所谓『匿名函数』,就是没有名字的函数,它无需使用def关键字去定义。
  • 语法:Python 中使用lambda关键字来定义『匿名函数』,格式为:lambda 参数: 表达式
  • 使用场景: 当一个函数只用一次、只做一点点小事,使用匿名函数会更简洁。
# 使用普通函数实现计算效果
def add(x, y):
    return x + y

def sub(x, y):
    return x - y

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

calculate(add, 30, 10)
calculate(sub, 30, 10)
# 使用匿名函数实现计算效果
def calculate(func, a, b):
    print(f'计算结果为:{func(a, b)}')

calculate(lambda x, y: x + y, 30, 10)
calculate(lambda x, y: x - y, 30, 10)
  • 特点:
  • 只能写一行,不能写多行代码。
  • 不能写代码块(if、for、while)
  • 冒号右边必须是表达式,且只能写一个表达式。
  • 执行结果自动作为返回值。
is_adult = lambda age: '成年' if age >= 18 else '未成年'
print(is_adult(18))
print(is_adult(13))

7. 几个数据处理函数

7.1. map 函数

  • map函数:对一组数据中的每一个元素,统一执行某种操作(加工),并生成一组新数据。
  • 语法格式:map(操作函数, 可迭代对象)
# 统一数据处理
nums = [10, 20, 30, 40]
# map函数的返回值是一个迭代器对象,需要我们自己去手动遍历,或者手动类型转换
result = map(lambda x: x * 2, nums)
print(list(result))
print(nums)

# 字符串转换
names = ('python', 'java', 'js')
result = map(lambda x: x.upper(), names)
print(tuple(result))
print(names)

# 类型转换
str_number = {'1', '2', '3'}
result = map(int, str_number)
print(set(result))
print(str_number)

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

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

7.2. filter 函数

  • filter函数:从一组数据中,筛选出符合条件的元素(过滤),并组成一组新数据。
  • 语法格式:filter(过滤函数, 可迭代对象)
# 筛选数值
nums = [10, 20, 30, 40, 50]
result = filter(lambda n: n > 30, nums)
print(list(result))
print(nums)

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

# 过滤一下非法字符串
names = ['张三', '', '李四', None, '王五']
result = filter(lambda n: n, names)
print(list(result))

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

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

7.3. sorted 函数

  • sorted函数:对一组数据进行排序,返回一组新数据。
  • 语法格式:sorted(可迭代对象, key=xxx, reverse=xxx)
# 数字排序
nums = [30, 40, 20, 10]
result = sorted(nums, reverse=True)
print(result)

# 按照字符串的长度去排序
names = ['python', 'sql', 'java']
result = sorted(names, key=len, reverse=True)
print(result)

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

# 我们之前讲的max函数、min函数,也可以传递key参数,用于设置筛选依据
result1 = max(persons, key=lambda p: p['age'])
result2 = min(persons, key=lambda p: p['age'])
print(result1)
print(result2)

7.4. 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, 10)
print(result)

# 字符串拼接
str_list = ['ab', 'cd', 'ef']
result = reduce(lambda a, b: a + b, str_list)
print(result)
赞(0)
未经允许不得转载:AI项目博客 » Python 学习笔记 18|重新认识函数

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册