一、函数参数的基本概念
- 参数:函数执行任务时所需的额外数据。
- 形参:定义函数时设置的参数,用标识符(变量)命名。
- 实参:调用函数时传入的真实数据。
二、Python 中形参的主要类型
根据定义方式和传递规则,形参可分为以下 5 类:
1. 位置参数
- 定义:函数中直接定义的变量(无默认值),是最基础的参数类型。
- 特点:
- 调用时必须按定义顺序传递参数,且每个位置参数都是必传项。
- 也支持通过 “关键字” 传递(即指定参数名赋值)。
- 示例:
def sum_number(a, b): # a、b为位置参数 return a + b # 按位置传递(顺序必须对应) print(sum_number(2, 3)) # 输出:5 # 按关键字传递(顺序可忽略) print(sum_number(b=3, a=2)) # 输出:5
- 错误示例:若少传参数,会触发
TypeError
(提示缺少必传参数)。
2. 默认参数
- 定义:在位置参数后通过赋值语法设置默认值的参数(
参数名=默认值
)。 - 特点:
- 调用时可传可不传(不传则使用默认值)。
- 定义位置必须在所有位置参数之后。
- 示例:
def power_number(x, y=2): # y为默认参数(默认值2) return x ** y print(power_number(3)) # 不传y,使用默认值2 → 3²=9 print(power_number(3, 3)) # 传y=3 → 3³=27
3. 关键字参数
- 定义:在函数参数中,通过
*
分隔后定义的参数(*
后的参数必须用关键字传递)。 - 特点:调用时必须通过 “参数名 = 值” 的形式传递,不能按位置传递。
- 示例:
def sum_number(a, *, b): # b为关键字参数(*后定义) return a + b print(sum_number(2, b=1)) # 正确:b必须用关键字传递 → 3 # print(sum_number(2, 1)) # 错误:b未用关键字传递(触发TypeError)
4. 不定项位置参数(*args
)
- 定义:通过
*args
定义,用于接收 0~n 个位置参数。 - 特点:
- 函数中最多只能定义 1 个
*args
。 - 接收的参数会自动组装成元组。
- 函数中最多只能定义 1 个
- 示例:
def sum_all(*args): # args接收所有位置参数,组装为元组 return sum(args) print(sum_all(1, 2, 3, 4)) # args=(1,2,3,4) → 求和结果10 print(sum_all()) # 可传0个参数 → 0
5. 不定项关键字参数(**kwargs
)
- 定义:通过
**kwargs
定义,用于接收 0~n 个关键字参数。 - 特点:
- 接收的参数会自动组装成字典(键为参数名,值为参数值)。
- 定义位置必须在所有其他参数之后。
- 示例:
def print_info(** kwargs): # kwargs接收所有关键字参数,组装为字典 for k, v in kwargs.items(): print(f"{k}: {v}") print_info(name="张三", age=18) # kwargs={'name':'张三', 'age':18} # 输出:name: 张三;age: 18
参数定义的顺序规则
不同类型参数在函数中的定义顺序必须遵循:
位置参数 → 默认参数 → *args → 关键字参数 → **kwargs
三、匿名函数(lambda)
-** 定义 :用lambda
关键字创建的 “无名称” 函数,函数体只有 1 行代码。
- 语法 :lambda [参数列表]: 函数体
(若需返回值,无需写return
,函数体结果即返回值)。
- 特点 **:
- 通常用于临时任务,复用性低。
- 本质是函数对象,可赋值给变量或作为参数传递。
-** 示例 **:
# 求两数之和
sum_num = lambda a, b: a + b
print(sum_num(2, 3)) # 输出:5
# 判断闰年(断言型逻辑)
is_leap = lambda year: (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
print(is_leap(2000)) # 输出:True(2000是闰年)
四、函数的类型(按参数和返回值分类)
根据是否有参数、是否有返回值,函数可分为 5 类:
类型 | 定义(参数 / 返回值) | 作用 | 示例 |
---|---|---|---|
任务型函数 | 无参数 + 无返回值 | 执行特定操作(如打印、写入) | def print_hello(): print("hello") |
生产型函数 | 无参数 + 有返回值 | 生成数据(如随机数、计算结果) | def get_rand(): return random.random() |
消费型函数 | 有参数 + 无返回值 | 处理输入数据(如发送消息) | def send_msg(msg): print(f"发送:{msg}") |
功能型函数 | 有参数 + 有返回值 | 对输入数据处理后返回结果 | def add(a, b): return a + b |
断言型函数 | 有参数 + 返回 bool 值 | 判断条件是否成立 | def is_even(n): return n % 2 == 0 |
五、函数作为参数的应用示例
函数是对象,可作为参数传递给其他函数,实现灵活的逻辑复用。
1. 执行任务型函数(execute)
def execute(task):
# 接收一个任务型函数(无参无返回值)并执行
task()
# 调用:传入lambda作为任务
execute(lambda: print("执行任务:打印Hello")) # 输出:执行任务:打印Hello
2. 处理生产型函数(get_level)
import random
def get_level(generator):
# 接收生产型函数(无参有返回值),根据返回值判断等级
score = generator() # 获取生成的分数
if score >= 90:
return "A"
elif score >= 80:
return "B"
else:
return "C"
# 调用:传入生成随机分数的lambda
print(get_level(lambda: random.randint(60, 100))) # 输出:随机分数对应的等级
3. 消费可迭代对象(each)
def each(iterable, consumer):
# 接收可迭代对象和消费型函数(有参无返回值),遍历并消费每个元素
for idx, value in enumerate(iterable):
consumer(idx, value) # 消费(索引,值)
# 调用:打印列表中每个元素及其索引
each([10, 20, 30], lambda i, x: print(f"索引{i}:值{x}"))
# 输出:索引0:值10;索引1:值20;索引2:值30
4. 处理功能型函数(computed、lb_map)
-
computed:实现两数计算
def computed(a, b, func): # 接收两个数和功能型函数(有参有返回值),执行计算 return func(a, b) # 调用:求和、求幂 print(computed(2, 3, lambda x, y: x + y)) # 输出:5(求和) print(computed(2, 3, lambda x, y: x ** y)) # 输出:8(求幂)
-
lb_map:映射多可迭代对象同位置元素
def lb_map(*iterables, func): # 接收多个可迭代对象和功能型函数,映射同位置元素 result = [] for items in zip(*iterables): # 按位置打包元素(如(1,4), (2,5)) result.append(func(*items)) # 用func处理打包后的元素 return result # 调用:两列表元素求和、求积 print(lb_map([1,2,3], [4,5,6], func=lambda x,y: x+y)) # 输出:[5,7,9] print(lb_map([1,2,3], [4,5,6], func=lambda x,y: x*y)) # 输出:[4,10,18]
5. 过滤数据(ls_filter,基于断言型函数)
def ls_filter(array, predicate):
# 接收列表和断言型函数(返回bool),保留满足条件的元素
return [x for x in array if predicate(x)]
# 调用:保留偶数、保留大于3的数
print(ls_filter([1,2,3,4,5], lambda x: x % 2 == 0)) # 输出:[2,4]
print(ls_filter([1,2,3,4,5], lambda x: x > 3)) # 输出:[4,5]
一、基础函数题
1. 身份证校验与性别判断
def is_true_gender(card):
if len(card) != 18:
return False, None
wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
yi = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
list01 = list(card)
s = 0
for i in range(17):
s = s + int(wi[i]) * int(list01[i])
y = s % 11
# 校验码验证 + 性别判断(倒数第二位奇数为男,偶数为女)
return yi[y] == list01[-1], None if yi[y] != list01[-1] else '男' if int(list01[-2]) % 2 else '女'
print(is_true_gender('341621200402261335')) # 输出:(True, '男')
2. 素数判断
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
print(is_prime(10)) # 输出:False
3. 手机号校验
def is_phone_number(numbers):
valid_second_digits = {'3', '4', '5', '6', '7', '8', '9'}
return (numbers.isdigit() and
len(numbers) == 11 and
numbers[0] == '1' and
numbers[1] in valid_second_digits)
print(is_phone_number('7460304977')) # 输出:False
二、高阶函数与 lambda 表达式
1. 查找首个满足条件的元素
def find(ls, condition):
for item in ls:
if condition(item):
return item
return None
# 示例:查找id<10的第一条数据
print(find([{"id": 10, "name": "chn"}, {"id": 2, "name": "xxd"}], lambda i: i['id'] < 10))
# 输出:{'id': 2, 'name': 'xxd'}
2. 遍历可迭代对象(带索引)
def each(iterable, functional):
for i, x in enumerate(iterable):
functional(i, x)
# a. 打印索引
each([1, 2, 3], lambda i, x: print(i)) # 输出:0 1 2
# b. 打印元素
each([{"id": 10}, {"id": 2}], lambda i, x: print(x)) # 输出:{'id': 10} {'id': 2}
3. 列表过滤(带索引条件)
def list_filter(ls, fn):
return [x for i, x in enumerate(ls) if fn(i, x)]
# a. 索引为奇数的元素
print(list_filter([1, 2, 3, 4, 5], lambda i, x: i % 2 == 1)) # 输出:[2, 4]
# b. 索引为奇数且元素为偶数
print(list_filter([1, 2, 3, 4, 5, 6], lambda i, x: i % 2 == 1 and x % 2 == 0)) # 输出:[4, 6]
# c. 字符串长度3<len<10
print(list_filter(['abcd', '12', 'long_str'], lambda i, x: 3 < len(x) < 10)) # 输出:['abcd']
4. 列表映射
def lb_map(ls, functional):
return [functional(x) for x in ls]
# 元素乘以3
print(lb_map([1, 2, 3], lambda x: x * 3)) # 输出:[3, 6, 9]
# 元素平方
print(lb_map([1, 2, 3], lambda x: x ** 2)) # 输出:[1, 4, 9]
5. 删除满足条件的前缀元素
def drop_while(ls, condition):
while ls and condition(ls[0]):
ls.pop(0)
return ls
print(drop_while([1, 2, 5, 1, 3], lambda x: x < 3)) # 输出:[5, 1, 3]
6. 保留满足条件的前缀元素
def take_while(ls, condition):
new_ls = []
for x in ls:
if condition(x):
new_ls.append(x)
else:
break # 一旦不满足条件立即停止
return new_ls
print(take_while([1, 2, 3, 4, 1], lambda x: x < 3)) # 输出:[1, 2]
三、列表组合题
交叉组合多个列表
def list_cross(*ls):
if not ls:
return []
result = [(x,) for x in ls[0]]
for sub_list in ls[1:]:
new_result = []
for item in result:
for x in sub_list:
new_result.append(item + (x,))
result = new_result
return result
# 示例:3个列表交叉组合
print(list_cross([1, 2], [3, 4], [5, 6]))
# 输出:[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
四、重点知识总结
- lambda 表达式:用于创建匿名函数,简化代码(如
lambda x: x*2
)。 - 高阶函数:接收函数作为参数(如
find
、each
、list_filter
),实现通用逻辑。 - 列表操作技巧:
drop_while
和take_while
处理前缀元素。list_cross
实现多列表笛卡尔积。