Python函数修炼指南:从重复复制到一招封装,匿名lambda顺带拿捏

📅 2026/7/23 2:55:46 👁️ 阅读次数 📝 编程学习
Python函数修炼指南:从重复复制到一招封装,匿名lambda顺带拿捏

前言

刚学代码的新手大概率踩过同一个坑:想要循环打印数字1~5,第一反应哐哐复制五条print,后来学会for循环才算摆脱复制粘贴工的命运。但新问题接踵而至:同样一段循环逻辑,代码里要调用三四次,难道每次都把循环再抄一遍?这时候,函数就是Python送给开发者的第一把“代码复用神器”。

今天顺着实战案例,把普通函数、参数玩法、解包传参、lambda匿名函数一次性梳理清楚,干货拉满,尽量不整枯燥官话。

一、函数诞生的核心意义:消灭重复代码

先回顾最原始的写法,我们想多次输出1~5:

print(1) print(2) print(3) print(4) print(5) print(1) print(2) print(3) print(4) print(5)

但凡需求改一点,比如打印1~6,两处代码全都要手动修改。改一处漏一处,bug随之诞生。

用上循环优化一轮:

for i in range(1,6): print(i) for i in range(1,6): print(i)

清爽不少,但依旧存在冗余。

函数登场!把固定逻辑打包封装,起个名字,想用直接调用

def my_print(): """打印1到5,函数文档注释,用来描述函数功能""" for i in range(1, 6): print(i) 想执行多少次,调用多少次 my_print() my_print() my_print()

优势一目了然:逻辑只写一遍,多处调用;后续修改规则,只需要改动函数内部,一处修改全局生效。

二、形参与实参:让函数摆脱“写死的数据”

上面这个函数有短板:起始、结束数字固定,灵活性极差。我们可以设置形参,调用时传入实参,让函数适配不同场景。

def my_print(start, stop, msg): """ 自定义区间打印 :param start: 循环起始值 :param stop: 循环终止值(range左闭右开) :param msg: 附带打印的文本 """ for i in range(start, stop): print(i, msg) my_print(1, 6, "好饿呀") my_print(55, 60, "开饭了")

文档注释强烈建议养成习惯,后期代码多了,不用翻函数内部就能看懂参数用途。

实战练习:带返回值的函数

函数不只是单纯打印内容,更常用的能力是计算后返回结果return

划重点:print仅仅是输出展示,本身没有返回值;return才是把运算结果交给外部变量接收。

案例1:求取两个数字之间所有奇数之和

def get_total(a, b): total = 0 for i in range(a, b+1): if i % 2: total += i return total res = get_total(10, 50) print(res)

案例2:阶乘求和(5!+4!+3!+2!+1!)

这里演示两种写法:嵌套单层循环 / 两个函数互相调用。工程里更推荐拆分函数,逻辑解耦,可读性更高。

# 方案1:函数拆分,各司其职 def get_mul(i): """计算单个数字的阶乘""" mul = 1 for j in range(1, i + 1): mul *= j return mul def get_sum(value): """累加1~value每个数字的阶乘""" total = 0 for i in range(1, value+1): total += get_mul(i) return total print(get_sum(5))

三、综合实战:函数拆分思想处理质数问题

写复杂逻辑时,千万不要把所有代码揉在一坨,遵循一个函数只干一件事。先抽离工具函数is_prime,专门用来判断数字是不是质数;再写业务函数批量筛选。

示例:寻找区间内,间隔固定差值的质数三元组

def is_prime(value): """判断一个数字是否为质数""" for i in range(2, value): if value % i == 0: return False else: return True def get_prime_pairs(a, b, c): """ 查找 [a,b]区间内质数三元组 (n, n+c, n+2c) :param a: 区间下限 :param b: 区间上限 :param c: 相邻数字差值 :return: 所有符合条件的元组列表 """ result = [] for i in range(a, b+1): if is_prime(i) and is_prime(i+c) and is_prime(i+c+c): result.append((i, i+c, i + c + c)) return result print(get_prime_pairs(500, 1000, 18))

这种拆分思路,后续想改成找质数对、统计质数数量,直接复用is_prime,不用重复编写质数判断代码。

四、参数进阶:默认参数、不定长参数、解包传参

1. 默认参数

调用函数时不传该参数,自动使用预设值

def my_print(msg="醒醒啦", n=1): for i in range(n): print(msg) my_print("醒醒啦", 10) my_print("开饭啦") my_print(n=10)

2. 不定长参数*args**kwargs

  • *args:收集所有位置实参,打包成元组
  • **kwargs:收集所有关键字实参,打包成字典
def my_print(*args, **kwargs): print("位置参数:", args) print("关键字参数:", kwargs) my_print(10, 20, 30, name="小明", age=20)

3. 序列/字典解包传参***

当数据提前存放在列表、字典中,一个个手动传参太麻烦,使用解包一键传入:

def add(a, b, c): return a + b + c datas = [10, 20, 30] print(add(*datas)) # 列表解包 def greet(name, age, addr): print(f"{name} 今年 {age} 岁,居住地址:{addr}") info = { "name": "小明", "age": 20, "addr": "郑州" } greet(**info) # 字典解包

日常爬虫、接口传参场景,解包会高频出现,务必熟练。

五、短小精干的匿名选手:lambda表达式

普通def定义的是具名函数,适合逻辑复杂、多行代码场景。如果只是简单一行运算,不想单独定义函数,lambda匿名函数直接上场。

语法模板:lambda 参数列表 : 返回表达式

# 无参数 f2 = lambda: print(888) f2() 无参数,带返回值 f3 = lambda: (100, 200, 300) print(f3()) 单个参数 f4 = lambda x: x + 100 print(f4(50)) 多参数 f5 = lambda x, y: x + y + 100 print(f5(100, 200)) 定义完立刻调用,用完即弃 print((lambda x, y, z: x + y + z)(10, 20, 30))

温馨提醒:lambda仅限单行简单逻辑!别强行把一堆循环判断塞进lambda,可读性直接崩盘,得不偿失。复杂逻辑老老实实使用def

六、总结复盘

  1. 函数核心价值:代码封装、逻辑复用,告别复制粘贴;
  2. def定义普通函数return向外返回数据,单纯print无法接收结果;
  3. 代码遵循单一职责:工具逻辑抽成独立函数,方便复用与调试;
  4. 参数体系循序渐进:普通形参 → 默认参数 →*args/**kwargs→ 解包传参;
  5. lambda适合一行简易运算,轻量化匿名函数,不要滥用;

函数是Python一切高级玩法的地基:装饰器、面向对象、回调、多线程,全部建立在函数基础之上。地基打牢固,后面进阶学习会顺畅一大截。