news 2026/4/27 6:52:43

Day 11:【99天精通Python】函数进阶 - *args、**kwargs 与 Lambda 表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Day 11:【99天精通Python】函数进阶 - *args、**kwargs 与 Lambda 表达式

Day 11:【99天精通Python】函数进阶 - *args、**kwargs 与 Lambda 表达式

前言

欢迎来到第11天!

在昨天的课程中,我们学会了定义标准的函数,参数的数量在定义时就是固定的(比如def add(a, b)必须传两个数)。

但在实际开发中,情况往往没那么简单。比如:

  • 你想写一个sum_all()函数,能计算任意数量数字的和(可能是2个,也可能是100个)。
  • 你想写一个能够处理各种配置选项的函数,但不想写几十个默认参数。
  • 有些简单的函数(比如x + 1)只用一次,专门写个def显得太繁琐。

今天,我们将解锁Python函数的"完全体"形态,学习动态参数匿名函数

本节内容:

  • *args:接收任意数量的位置参数
  • **kwargs:接收任意数量的关键字参数
  • 参数的混合使用顺序
  • 解包参数(Unpacking)
  • Lambda 表达式(匿名函数)
  • Lambda 与高阶函数(map, filter, sorted)

一、动态参数:处理不确定数量的输入

1.1 *args:可变位置参数

当你不知道用户会传多少个位置参数时,可以使用*args
Python会将所有多余的位置参数打包成一个元组(Tuple)

语法

deffunc(*args):print(args)

注意args只是个约定俗成的名字,关键是那个星号*。你写*numbers也可以。

示例:万能求和函数

defsum_all(*numbers):"""计算任意个数字的和"""total=0fornuminnumbers:total+=numreturntotalprint(sum_all(1,2))# 3print(sum_all(1,2,3,4))# 10print(sum_all())# 0

1.2 **kwargs:可变关键字参数

如果你想接收任意数量的key=value形式的参数,可以使用**kwargs
Python会将它们打包成一个字典(Dictionary)

语法

deffunc(**kwargs):print(kwargs)

注意kwargs代表 “keyword arguments”,关键是双星号**

示例:用户信息记录

defprint_info(name,**details):print(f"Name:{name}")forkey,valueindetails.items():print(f"{key}:{value}")print_info("Alice",age=25,city="New York")# 输出:# Name: Alice# age: 25# city: New Yorkprint_info("Bob",job="Engineer",status="Single",level=99)

二、参数的组合与解包

2.1 这里的顺序很重要!

如果一个函数同时包含了多种类型的参数,定义的顺序必须是:

  1. 位置参数(常规参数)
  2. *args(可变位置参数)
  3. 默认参数(关键字参数)
  4. **kwargs(可变关键字参数)
defmixed_func(a,b,*args,**kwargs):print(f"a={a}, b={b}")print(f"args={args}")print(f"kwargs={kwargs}")mixed_func(1,2,3,4,5,x=10,y=20)# 输出:# a=1, b=2# args=(3, 4, 5)# kwargs={'x': 10, 'y': 20}

2.2 参数解包:把列表"炸"开传进去

刚才我们是用*收集参数(打包),反过来,我们在调用函数时,也可以用*解散列表(解包)。

defadd(a,b,c):returna+b+c nums=[1,2,3]# 错误调用:add(nums) -> 报错,因为只传了1个参数(整个列表)# 正确调用(解包)print(add(*nums))# 等同于 add(1, 2, 3) -> 6

同理,**可以用来解包字典:

defintroduce(name,age):print(f"我是{name},今年{age}岁")info={"name":"小明","age":18}# introduce(info) -> 报错introduce(**info)# 等同于 introduce(name="小明", age=18)

三、Lambda 表达式:一行代码的函数

3.1 什么是 Lambda?

Lambda 表达式(也称匿名函数)是一种定义简单函数的快捷方式。它没有名字,通常只包含一行代码。

语法

lambda参数:表达式
  • 关键字lambda开头。
  • 参数可以有多个,用逗号分隔。
  • 冒号后是表达式,自动返回该表达式的计算结果(不需要return)。

对比

# 普通函数defsquare(x):returnx*x# Lambda 函数square_lambda=lambdax:x*xprint(square(5))# 25print(square_lambda(5))# 25

3.2 什么时候用 Lambda?

Lambda 通常不单独使用(单独用不如直接 def),它主要是作为参数传递给其他函数(如高阶函数)。

场景 1:配合 sort() 排序

比如我们有一个字典列表,想根据字典里的某个键排序。

students=[{"name":"Alice","age":25},{"name":"Bob","age":20},{"name":"Charlie","age":22}]# 按年龄排序# sort(key=函数) -> 这里需要一个函数,告诉sort按什么排students.sort(key=lambdas:s["age"])print(students)# [{'name': 'Bob', 'age': 20}, {'name': 'Charlie', 'age': 22}, {'name': 'Alice', 'age': 25}]
场景 2:配合 map() 映射

map(func, iterable):对序列中的每个元素应用 func。

nums=[1,2,3,4,5]# 将所有数字平方squared=list(map(lambdax:x**2,nums))print(squared)# [1, 4, 9, 16, 25]
场景 3:配合 filter() 过滤

filter(func, iterable):保留 func 返回 True 的元素。

nums=[1,2,3,4,5,6]# 筛选偶数evens=list(filter(lambdax:x%2==0,nums))print(evens)# [2, 4, 6]

四、实战练习

练习1:超级连接器

编写一个函数concat_str(*args, sep="/"),它可以接收任意多个字符串,并用指定的分隔符(默认是/)连接它们。

defconcat_str(*args,sep="/"):returnsep.join(args)print(concat_str("home","user","docs"))# home/user/docsprint(concat_str("2026","01","11",sep="-"))# 2026-01-11

练习2:自定义排序逻辑

有一个元组列表[(1, 'one'), (3, 'three'), (2, 'two')],请使用sorted()lambda表达式,按照元组的第二个元素(字符串)的长度进行排序。

data=[(1,'one'),(3,'three'),(2,'two')]# 按字符串长度排序 ('one':3, 'three':5, 'two':3)# 注意:one和two长度一样,保持原序sorted_data=sorted(data,key=lambdax:len(x[1]))print(sorted_data)# [(1, 'one'), (2, 'two'), (3, 'three')]

五、常见问题

Q1:*args**kwargs必须这么写吗?

不是强制的。你完全可以写*vars**options。但是,*args**kwargs是Python社区的硬性约定,为了让别人能看懂你的代码,请务必遵守这个命名

Q2:Lambda 能包含复杂的逻辑吗?

不能。Lambda 只能包含一个表达式。它不能包含赋值语句(x=1)、循环(for)、流程控制(if...elif,但可以用三元运算符x if c else y)。如果逻辑复杂,请老老实实写def

Q3:args是列表吗?kwargs是字典吗?

  • args本质上是一个元组 (tuple)(不可变)。
  • kwargs本质上是一个字典 (dict)

六、小结

函数进阶

动态参数

匿名函数 Lambda

参数解包

*args (接收位置参数 -> 元组)

**kwargs (接收关键字参数 -> 字典)

lambda x: x+1

配合 sorted/map/filter 使用

*列表 -> 解包为位置参数

**字典 -> 解包为关键字参数

关键要点

  1. 想让函数接收任意个参数?用*args**kwargs
  2. *args把多余参数打包成元组,**kwargs打包成字典。
  3. lambda适合写那种"用完即扔"的短小函数,特别是在排序和数据处理时。
  4. 参数解包func(*list)是非常实用的技巧。

七、课后作业

  1. 最大值函数:不要使用内置的max(),编写一个接受任意数量数字的函数my_max(*args)并返回最大值。
  2. 字典构造器:编写一个函数make_dict(**kwargs),它接收任意关键字参数,并返回一个字典,但要求所有的key都必须转换为大写。
    • 输入:make_dict(a=1, b=2)
    • 输出:{'A': 1, 'B': 2}
  3. 复杂排序:有一个学生列表students = [{'name':'Tom','score':80}, {'name':'Jerry','score':90}, {'name':'Spike','score':80}]。请按照分数降序排序;如果分数相同,则按名字字母序升序排序。(提示:元组比较规则(score, name))。

下节预告

Day 12:文件操作 (File I/O)- 写了这么多代码,结果一关机数据就没了?明天我们学习如何读写文件,把数据持久化保存下来!


系列导航

  • 上一篇:Day 10 - 函数基础
  • 下一篇:Day 12 - 文件操作(待更新)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 18:36:45

工业环境下继电器模块电路图抗干扰设计指南

工业环境下继电器模块抗干扰设计实战指南:从原理到PCB落地在自动化产线的深夜,你是否经历过这样的场景?PLC控制柜里的继电器突然“啪”地一声自启动,电机毫无征兆地运转起来——而操作员根本没有下发指令。排查数小时后发现&#…

作者头像 李华
网站建设 2026/4/23 18:57:34

从零实现多层PCB生产流程:实验室级小批量制作方案

实验室里的“芯片工厂”:如何亲手做出一块四层PCB?你有没有过这样的经历?设计好了一块精密的四层板,满怀期待地发给厂家打样,结果等了五天,收货一看——线宽偏差、孔铜太薄、甚至内层错位。更糟的是&#x…

作者头像 李华
网站建设 2026/4/23 18:57:34

HBuilderX Windows环境配置:新手教程(零基础必看)

从零开始玩转 HBuilderX:Windows 下的前端开发第一站你是不是也曾在搜索“前端怎么入门”时,被一堆专业术语搞得晕头转向?Webpack、Babel、TypeScript、Node.js……光是名字就让人想放弃。其实,前端开发的第一步,完全可…

作者头像 李华
网站建设 2026/4/23 18:58:37

HBuilderX下载Windows版实战案例:适用于前端初学者

从零开始:手把手教你下载安装 HBuilderX(Windows 版)——前端新手的第一步 你是不是刚接触前端开发,面对五花八门的编辑器无从下手?VS Code 功能强大但配置复杂,Sublime Text 快速轻巧却要自己“拼装”插件…

作者头像 李华
网站建设 2026/4/23 18:59:00

基于FPGA的4位全加器设计与七段显示实战案例

FPGA实战入门:从全加器到七段数码管显示的完整数字系统构建你有没有想过,计算机最底层的“计算”到底是怎么发生的?两个数相加——这个在我们看来再简单不过的操作,其实背后藏着一套精密的逻辑体系。今天,我们就用一块…

作者头像 李华