考点 8. 函数的定义和调用
掌握 Python 函数的定义、调用,正确认识函数的参数、返回值,正确判断变量的作用域。
函数是组织好的、可重复使用的、用来实现单一或相关功能的代码段;它能提高代码的复用性、可读性和可维护性,是 Python 编程的核心基础。
一、函数的定义
函数的定义是创建可复用代码块的过程,是使用函数的第一步,必须遵循严格的语法规则。
函数定义的完整语法结构如下:
def 函数名(参数列表):
"""文档字符串(Docstring):描述函数功能、参数、返回值等"""
# 函数体:实现具体功能的代码逻辑
执行语句1
执行语句2
...
return 返回值 # 可选,无return则默认返回None
各部分说明见表 8-29 所列。
表 8-29 函数语法
| 组成部分 | 作用与要求 |
|---|---|
| def | 定义函数的关键字,必须小写,且是定义函数的唯一入口,不能省略 |
| 函数名 | 遵循 Python 的命名规范:(1)只能由字母、数字、下划线组成,不能以数字开头;(2)小写为主,多个单词用下划线分隔(蛇形命名法);(3)见名知意(如calculate_sum而非func1) |
| 参数列表 | 函数的"输入",可选[无参数时写空括号()];多个参数用逗号分隔;参数定义有严格的顺序规则 |
| 冒号(:) | 函数定义行的结尾必须加冒号,用于标识函数体的开始 |
| 文档字符串 | 可选,用三引号("""...""")包裹;可通过函数名.__doc__或help(函数名)查看;用于说明函数的功能、参数含义、返回值类型等 |
| 函数体 | 函数的核心逻辑,必须缩进(通常4个空格),缩进不一致会报IndentationError |
| return | 函数的"输出",可选;执行到return时函数立即终止,后续代码不会执行;无return则函数执行完后返回None |
【例 8.14】S 打印固定提示信息,无须输入,也无须输出。
def print_welcome():
"""打印欢迎语"""
print("欢迎使用Python函数教程!")
# 无 return;默认返回 None
# 验证返回值
result = print_welcome()
print(f"函数返回值:{result}") # 输出:函数返回值:None
【例 8.15】计算两个数的乘积,需要输入两个数,输出乘积结果。
def multiply(num1,num2):
"""
计算两个数值的乘积
:param num1:第一个乘数(数值类型)
:param num2:第二个乘数(数值类型)
:return:两个数的乘积(数值类型)
"""
product = num1 * num2
return product # 返回计算结果
# 验证返回值
product_result = multiply(3.5,4)
print(f"3.5 × 4 = {product_result}") # 输出:3.5 × 4 = 14.0
二、函数的参数及调用
函数定义后不会自动执行,必须通过"调用"触发执行,调用的核心是"传参匹配",不同的参数类型对应不同的调用方式。
1. 函数调用的基本语法
函数名(传入的参数列表)
调用的核心规则:传入的参数须与定义的参数在数量、类型、顺序(位置参数)上匹配(默认参数除外)。
2. 不同参数类型的调用方式
(1)形参与实参
形参和实参是函数定义与调用时的"一对一"对应概念,核心区别在于是否具有具体值,以及存在阶段的不同,具体见表 8-30 所列。
表 8-30 形参与实参
| 概念 | 中文名称 | 定义场景 | 核心特点 |
|---|---|---|---|
| 形参(param) | 形式参数 | 函数定义时 | 写在"def 函数名()"括号内的变量,仅作为"占位符",无具体值,规定函数能接收的输入 |
| 实参(argument) | 实际参数 | 函数调用时 | 传入"函数名()"括号内的具体值(可以是常量、变量、表达式等),会赋值给对应的形参 |
# 定义函数时:a和b是形参(仅占位,无具体值)
def add(a,b):
return a + b
# 调用函数时:3和5是实参(具体值,会赋值给形参a和b)
result = add(3,5)
print(result) # 输出:8
(2)位置参数
按函数定义时的参数顺序传值,数量必须完全匹配。
# 先定义函数
def add(a,b):
return a + b
# 位置参数调用:按顺序传a=2,b=3
result1 = add(2,3)
print(result1) # 输出:5
# 错误示例:参数数量不匹配(定义2个,传1个)
# result2 = add(2) # 报 TypeError:add() missing 1 required positional argument:'b'
(3)关键字参数
通过"参数名=值"的形式传值,顺序可以打乱,核心是"参数名匹配"。
# 沿用上面的add函数 # 关键字参数调用:顺序打乱,仍能正确匹配
result3 = add(b=5,a=4)
print(result3) # 输出:9
# 混合位置参数和关键字参数(位置参数必须在前面)
result4 = add(6,b=7)
print(result4) # 输出:13
# 错误示例:关键字参数放在位置参数前
# result5 = add(a=8,9) # 报 SyntaxError:positional argument follows keyword argument
(4)默认参数
定义时带默认值的参数,调用时可省略,若传值则覆盖默认值。
# 省略所有默认参数:只传name
print_user_info("张三") # 输出:姓名:张三,年龄:18,性别:未知
# 覆盖部分默认参数: name和age,省略gender
print_user_info("李四",25) # 输出:姓名:李四,年龄:25,性别:未知
# 覆盖所有默认参数: name,age,gender
print_user_info("王五",30,"男") # 输出:姓名:王五,年龄:30,性别:男
# 用关键字参数覆盖默认参数
print_user_info("赵六",gender="女") # 输出:姓名:赵六,年龄:18,性别:女
(5)可变长度参数
*args:接收任意数量的位置参数,调用时直接传多个值即可。
**kwargs:接收任意数量的关键字参数,调用时传多个key=value即可。
# 定义带可变参数的函数
def func(*args, **kwargs):
print("位置参数元组:",args)
print("关键字参数字典:",kwargs)
# 调用:传任意数量的位置参数和关键字参数
func(1,2,3,name="小明",age=10)
# 输出:
# 位置参数元组:(1,2,3)
# 关键字参数字典:{'name':'小明','age':10}
# 也可以不传可变参数(不会报错)
func()
# 输出:
# 位置参数元组:()
# 关键字参数字典:{}
3. 函数调用的进阶场景
函数调用的进阶场景是嵌套调用。
# 定义辅助函数:计算平方
def square(x):
return x * x
# 定义主函数:计算两个数的平方和
def sum_of_squares(a,b):
# 内部调用square函数
a_sq = square(a)
b_sq = square(b)
return a_sq + b_sq
# 调用主函数
result = sum_of_squares(3,4)
print(result) # 输出:25(3²+4²=9+16=25)
三、函数的返回值
1. 返回值的核心概念
函数的返回值是函数执行完成后,通过return语句传递给调用者的输出结果。
(1)没有return语句的函数,默认返回None。
- (2)执行到return语句时,函数会立即终止(后续代码不再执行)。
- (3)返回值既可以被变量接收、直接使用(如打印),也可以忽略。
基础语法结构如下:
def 函数名(参数):
函数体
return 返回值 # 可选,无return则返回None
2. 返回值的多种形式
(1)无返回值(默认返回 None)
当函数只需执行操作(如打印、修改数据),无须返回结果时,可省略return,或显式返回None。
# 省略return;默认返回None
def print_hello():
print("Hello Python!")
# 调用函数;接收返回值
result1 = print_hello()
print(result1) # 输出:Hello Python!然后输出None
# 显式返回None(与省略return效果一致)
def func():
return None
result2 = func()
print(result2) # 输出:None
(2)返回单个值
返回单个值是最常用的场景,return后跟任意类型的单个值(数字、字符串、列表、对象等)。
# 返回数字
def add(a,b):
return a + b
sum_result = add(3,5)
print(sum_result) # 输出:8
# 返回字符串
def get_greeting(name):
return f"Hello,{name}!"
greeting = get_greeting("张三")
print(greeting) # 输出:Hello,张三!
# 返回列表
def get_list():
return [1,2,3,4]
lst = get_list()
print(lst) # 输出:[1,2,3,4]
(3)返回多个值
Python 支持"看似返回多个值",本质是将多个值打包成元组返回,调用时可通过多个变量自动解包。
核心原理:return a,b,c等价于return (a,b,c)。
# 返回多个值(姓名、年龄、成绩)
def get_student_info():
name = "李四"
age = 18
score = 95.5
return name,age,score # 打包为元组返回
# 方式1:用单个变量接收(得到元组)
info = get_student_info()
print(info) # 输出:('李四',18,95.5)
# 方式2:多个变量解包接收(更常用)
name,age,score = get_student_info()
print(f"姓名:{name},年龄:{age},成绩:{score}") # 输出:姓名:李四,年龄:18,成绩:95.5
# 方式3:解包时忽略部分值(用_占位)
name,_,score = get_student_info()
print(f"姓名:{name},成绩:{score}") # 输出:姓名:李四,成绩:95.5
(4)返回空值(显式返回 None)
虽然省略return会默认返回None,但在以下场景建议显式写出return None。
- ①函数有返回值的预期,但某些分支无有效结果。
- ②提高代码可读性,明确告知调用者"此分支无返回结果"。
def find_num(lst,target):
"""在列表中查找目标值,找到返回索引,未找到返回None"""
for index,num in enumerate(lst):
if num == target:
return index # 找到则返回索引
# 未找到显式返回None
return None
# 测试
nums = [1,2,3,4]
print(find_num(nums,3)) # 输出:2
print(find_num(nums,5)) # 输出:None
(5)返回函数(高阶函数)
函数可以作为返回值,这是 Python 高阶函数的核心特性之一,常用于闭包、装饰器等场景。
# 定义外层函数;返回内层函数
def outer(x):
def inner(y):
return x + y
return inner # 返回内层函数(未执行)
# 调用outer,得到一个固定x=5的inner函数
add5 = outer(5)
# 调用inner函数,传入y=10
result = add5(10)
print(result) # 输出:15
# 链式调用
result2 = outer(3)(4) # 等价于inner=outer(3);inner(4)
print(result2) # 输出:7
3. `return`的关键特性
(1)return 终止函数执行
函数中return语句执行后,后续代码立即停止运行,这是控制函数流程的重要方式。
def test_return():
print("执行第一行代码")
return # 终止函数
print("执行第二行代码") # 不会执行
result = test_return()
print(result) # 输出:执行第一行代码 None
(2)条件返回(多分支 return)
函数中可以根据不同的条件返回不同的值,需确保所有分支都有明确的返回逻辑(避免隐式返回None)。
def get_grade(score):
"""根据分数返回等级"""
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 60:
return "C"
else:
return "D"
# 测试
print(get_grade(95)) # 输出:A
print(get_grade(75)) # 输出:C
四、递归函数
1. 递归函数的核心概念
递归函数(Recursive Function)是指在函数体内调用自身的函数,它是一种通过将大问题拆解为规模更小的同类型问题来解决问题的编程思想。
(1)递归的核心思想
递归的本质是"分治",把一个复杂问题拆分成和原问题逻辑相同但规模更小的子问题,直到子问题简单到可以直接解决(终止条件),然后通过子问题的解反向推导出原问题的解。例如,计算5!(5的阶乘):5!=5×4!;4!=4×3!;...;1!=1(终止条件);找迷宫出口:每走一步都判断是否为出口(终止条件),不是则向更小的区域继续找。
- (2)递归必须满足两个核心条件,缺少任何一个条件都会导致无限递归(程序崩溃)。
- ①终止条件(基线条件):递归调用的"终点",当满足该条件时,函数不再调用自身,直接返回结果。
- ②递归条件:函数调用自身,且每次调用都向"终止条件"靠近(问题规模减小)。
2. 递归函数的编写步骤
编写递归函数的核心是"先确定终止条件,再写递归逻辑",具体步骤如下。
(1)分析问题,确定终止条件(最简单的子问题的解)。
(2)确定递归公式(原问题如何拆分为子问题)。
- (3)编写函数:先判断终止条件,再执行递归调用。
3. 基础递归函数的经典示例
(1)计算阶乘
- ①阶乘的定义:n!=n×(n-1)×(n-2)×...×1(n≥1)。
a. 终止条件:1!=1(0!也定义为1)。
b. 递归公式:n!=n×(n-1)!。
- ②代码实现:
def factorial(n):
# 1. 终止条件:n=0或n=1时,阶乘为1
if n == 0 or n == 1:
return 1
# 2. 递归条件:n!=n×(n-1)!,调用自身并缩小问题规模
return n * factorial(n - 1)
# 测试
print(factorial(5)) # 输出:120(5×4×3×2×1)
print(factorial(0)) # 输出:1(符合数学定义)
- ③执行过程拆解(以factorial(3)为例)。
factorial(3)→3×factorial(2)
factorial(2)→2×factorial(1)
factorial(1)→终止条件,返回1
- ④反向计算。
2×1=2→3×2=6→最终返回6。
(2)计算斐波那契数列的数列
- ①斐波那契数列的定义:数列1,1,2,3,5,8,13,...(第1、2项为1)。
a. 终止条件:n=1或n=2时,值为1。
b. 递归公式:fib(n)=fib(n-1)+fib(n-2)(n>2)。
- ②代码实现:
def fibonacci(n):
# 1. 终止条件:第1、2项为1
if n == 1 or n == 2:
return 1
# 2. 递归条件:第n项 = 第n-1项 + 第n-2项
return fibonacci(n - 1) + fibonacci(n - 2)
# 测试
print(fibonacci(5)) # 输出:5(1,1,2,3,5)
print(fibonacci(7)) # 输出:13
(3)递归求和(计算1到n的和)
- ①求和定义:
a. 终止条件:n=1时,和为1。
b. 递归公式:sum(n)=n+sum(n-1)。
- ②代码实现:
def sum_n(n):
# 终止条件
if n == 1:
return 1
# 递归条件
return n + sum_n(n - 1)
# 测试
print(sum_n(5)) # 输出:15(1+2+3+4+5)
print(sum_n(10)) # 输出:55
五、匿名函数
1. 匿名函数的核心概念
匿名函数(Lambda Function)是用lambda关键字定义的简短、临时使用的函数,它没有正式的函数名,因此被称为"匿名"。
- (1)核心特点:语法简洁,只能写单行表达式,适用于简单逻辑,常配合高阶函数(如map/filter)使用。
- (2)本质:lambda是一个表达式,不是语句,它可以出现在普通函数不能出现的地方(如列表推导式、函数参数中)。
2. 匿名函数的语法规则
lambda 参数列表: 表达式
匿名函数语法的具体规则说明见表 8-31 所列。
表 8-31 匿名函数语法
| 组成部分 | 规则与说明 |
|---|---|
| lambda | 定义匿名函数的关键字(必须小写),相当于普通函数的def |
| 参数列表 | 与普通函数的参数规则一致:(1)可写位置参数、默认参数;(2)多个参数用逗号分隔;(3)无参数则写空 |
| 冒号(:) | 分隔参数列表和表达式,必须写 |
| 表达式 | 函数的"返回值",规则:(1)只能是单个表达式(不能写多行代码、循环、if-else语句块);(2)表达式的结果就是函数的返回值(无须写return);(3)表达式可以使用参数列表中的参数 |
3. 匿名函数的基本用法
(1)无参数的匿名函数
无参数的匿名函数适用于返回固定值的简单场景。
# 无参数;返回固定字符串
hello = lambda: "Hello Python!"
print(hello()) # 输出:Hello Python!
(2)单个参数的匿名函数
# 计算参数的平方
square = lambda x: x * x
print(square(4)) # 输出:16
# 字符串处理(转大写)
upper_str = lambda s: s.upper()
print(upper_str("hello")) # 输出:HELLO
(3)多个参数的匿名函数
# 计算两个数的乘积
multiply = lambda a,b: a * b
print(multiply(3,6)) # 输出:18
# 带默认参数的匿名函数
power = lambda x,n=2: x ** n
print(power(3)) # 输出:9(默认平方)
print(power(3,3)) # 输出:27(立方)
六、函数的作用域
1. 作用域的核心概念
函数的作用域(Scope)是指变量的可见范围,即变量在代码中可以被访问、修改的位置。Python 中变量的作用域由其定义的位置决定,核心原则是变量在哪里定义,就决定了它能被谁访问。
2. 作用域的分类
在 Python 中有全局和函数两种作用域。
(1)全局作用域
全局作用域在程序执行时创建,结束时销毁。所有函数以外的区域都是全局作用域,在全局作用域中定义的变量都属于全局变量,可以在程序的任意位置被访问。
# 全局变量
total = 0
def add(a,b): # 读取全局变量
global_total = total + a + b
print("全局 total + a + b =",global_total)
add(3,5) # 输出:全局 total + a + b = 8
(2)函数作用域
函数作用域在函数调用时创建,调用结束时销毁。函数每调用一次就会产生一个新的函数作用域,在函数作用域中定义的变量都是局部变量,只能在函数内部被访问。
# 全局变量
num = 100
def test_local(): # 局部变量(与全局变量同名)
num = 10
print("函数内的 num(局部):",num) # 输出:10(优先用局部)
test_local()
print("函数外的 num(全局):",num) # 输出:100(全局变量未被修改)
3. `global` 关键字
(1)作用
声明变量是全局变量,使在函数内可以修改全局变量。
(2)规则
- ①global必须写在函数内部及使用变量之前。
- ②可同时声明多个全局变量,如global a,b,c。
- ③声明的变量如果不在全局作用域中,那么会创建对应的全局变量。
def create_global():
# 声明并创建全局变量 new_var
global new_var
new_var = "我是新的全局变量"
create_global()
print(new_var) # 输出:我是新的全局变量(全局变量已创建)
七、Python 的内置函数
Python 的内置函数是指无须导入任何模块(如math、os),直接可以使用的函数,它们被封装在 Python 的内置命名空间中,覆盖了数据类型转换、序列操作、逻辑判断、输入输出等核心场景。
1. 数据类型转换
类型转换函数用于不同数据类型之间的转换,是最基础、最常用的内置函数,见表 8-32 所列。
表 8-32 类型转换函数
| 函数 | 功能描述 | 示例 |
|---|---|---|
| int(x) | 转换为整数(x可为字符串/浮点数) | int("123")→123,int(3.9)→3 |
| float(x) | 转换为浮点数 | float("3.14")→3.14,float(5)→5.0 |
| str(x) | 转换为字符串 | str(123)→"123",str([1,2])→"[1,2]" |
| bool(x) | 转换为布尔值(空/0为False,其余为True) | bool(0)→False,bool("abc")→True |
| list(x) | 转换为列表(x为可迭代对象) | list((1,2,3))→[1,2,3],list("abc")→["a","b","c"] |
| tuple(x) | 转换为元组 | tuple([1,2])→(1,2) |
| dict(x) | 转换为字典(x为键值对可选代对象) | dict([("a",1),("b",2)])→{"a":1,"b":2} |
| set(x) | 转换为集合(去重) | set([1,2])→{1,2} |
# 字符串转整数(处理用户输入)
user_input = input("请输入数字:") # 输入"100"
num = int(user_input)
print(num + 50) # 输出:150
# 列表转集合去重
nums = [1,2,2,3,3,3]
unique_nums = set(nums)
print(unique_nums) # 输出:{1,2,3}
# 可迭代对象转字典
key_value_pairs = [("name","张三"),("age",20)]
user_info = dict(key_value_pairs)
print(user_info) # 输出:{'name':'张三','age':20}
2. 序列/集合操作类
序列/集合操作类函数用于操作列表、元组、字符串、字典等可迭代对象,是处理数据的核心工具。
- (1)`len(iterable)`:获取可迭代对象的长度。
print(len("hello")) # 输出:5(字符串长度)
print(len([1,2,3])) # 输出:3(列表长度)
print(len({"a":1,"b":2})) # 输出:2(字典键的数量)
- (2)`max(iterable)`/`min(iterable)`:获取最大值/最小值。
nums = [3,1,4,2]
print(max(nums)) # 输出:4
print(min(nums)) # 输出:1
# 带 key 参数(按指定规则比较)
students = [{"name":"张三","age":20},{"name":"李四","age":18}]
print(max(students,key=lambda x: x["age"])) # 输出:{'name':'张三','age':20}
- (3)`sum(iterable)`:计算可迭代对象的和。
print(sum([1,2,3,4])) # 输出:10
print(sum((1.5,2.5))) # 输出:4.0
# 带初始值(默认0)
print(sum([1,2],10)) # 输出:13(1+2+10)
- (4)`sorted(iterable,key=None,reverse=False)`:排序。
- ①key:排序依据的函数。
- ②reverse:是否降序(默认False升序)。
# 基础排序
nums = [3,1,4,2]
print(sorted(nums)) # 输出:[1,2,3,4]
print(sorted(nums,reverse=True)) # 输出:[4,3,2,1]
# 按自定义规则排序
strings = ["apple","banana","cherry"]
# 按字符串长度排序
print(sorted(strings,key=lambda x: len(x))) # 输出:['apple','banana','cherry']
- (5)`enumerate(iterable,start=0)`:枚举(返回索引+元素)。
fruits = ["apple","banana","orange"]
# 枚举;默认索引从0开始
for idx,fruit in enumerate(fruits):
print(f"索引{idx}:{fruit}")
# 输出:
# 索引0:apple
# 索引1:banana
# 索引2:orange
# 索引从1开始
for idx,fruit in enumerate(fruits,start=1):
print(f"序号{idx}:{fruit}")
- (6)`zip(*iterables)`:打包多个可迭代对象(按位置配对)。
a = [1,2,3]
b = ["a","b","c"]
# 打包为元组迭代器
zipped = zip(a,b)
print(list(zipped)) # 输出:[(1,'a'),(2,'b'),(3,'c')]
# 长度不一致时;按最短的来
c = [True,False]
print(list(zip(a,c))) # 输出:[(1,True),(2,False)]
- (7)`reversed(sequence)`:反转序列(返回迭代器)。
nums = [1,2,3]
print(list(reversed(nums))) # 输出:[3,2,1]
print("".join(reversed("hello"))) # 输出:olleh
3. 输入/输出类
- (1)`print(*objects,sep=' ',end='\n',file=None)`:输出内容。
- ①sep:多个对象之间的分隔符(默认空格)。
- ②end:输出结尾的字符(默认换行)。
- ③file:输出到文件(默认控制台)。
# 基础输出
print("Hello","Python") # 输出:Hello Python
# 自定义分隔符
print(1,2,3,sep="-") # 输出:1-2-3
# 自定义结尾(不换行)
print("第一行",end=";")
print("第二行") # 输出:第一行;第二行
# 输出到文件
with open("test.txt","w",encoding="utf-8") as f:
print("写入文件",file=f)
- (2)`input(prompt=None)`:获取用户输入(返回字符串)。
name = input("请输入你的名字:") # 输入:张三
print(f"你好,{name}!") # 输出:你好,张三!
# 输入数字需手动转换类型
age = int(input("请输入你的年龄:")) # 输入:20
print(f"明年你{age+1}岁") # 输出:明年你21岁
4. 逻辑判断/对象检查类
- (1)`type(object)`:获取对象的类型。
print(type(123)) # 输出:<class 'int'>
print(type("hello")) # 输出:<class 'str'>
print(type([1,2])) # 输出:<class 'list'>
- (2)`isinstance(object,classinfo)`:判断对象是否为指定类型。
比type更灵活,支持继承关系,如isinstance(True,int)返回True。
print(isinstance(123,int)) # 输出:True
print(isinstance("hello",str)) # 输出:True
print(isinstance([1,2],(list,tuple))) # 输出:True(匹配元组中的任意类型)
- (3)`id(object)`:获取对象的内存地址。
a = 10
b = a
print(id(a)) # 输出:如140708467867904
print(id(b)) # 输出:与a相同(指向同一内存)
- (4)`all(iterable)`/`any(iterable)`:判断可迭代对象的布尔值。
- ①all:所有元素为True才返回True。
- ②any:任意一个元素为True就返回True。
nums1 = [True,1,"abc"]
print(all(nums1)) # 输出:True
print(any(nums1)) # 输出:True
5. 数学计算类
- (1)`abs(x)`:获取绝对值。
print(abs(-5)) # 输出:5
print(abs(3.14)) # 输出:3.14
- (2)`round(number,ndigits=None)`:四舍五入。
ndigits:保留的小数位数(默认None,取整)。
print(round(3.1415)) # 输出:3
print(round(3.1415,2)) # 输出:3.14
print(round(3.5)) # 输出:4(注意:Python的四舍五入是"银行家舍入",偶数优先)
- (3)`pow(base,exp,mod=None)`:计算幂/取模。
- ①pow(a,b) = a ** b。
- ②pow(a,b,c) = (a ** b) % c(更高效)。
print(pow(2,3)) # 输出:8
print(pow(2,3,5)) # 输出:3(8%5=3)
6. 迭代器/生成器类
- (1)`range(start,stop,step)`:生成整数序列(返回`range`对象)。
- ①start:起始值(默认0)。
- ②stop:终止值(不包含)。
- ③step:步长(默认1)。
# 生成0~4的整数
print(list(range(5))) # 输出:[0,1,2,3,4]
# 生成2~8(步长2)
print(list(range(2,9,2))) # 输出:[2,4,6,8]
# 倒序生成
print(list(range(5,0,-1))) # 输出:[5,4,3,2,1]
- (2)`iter(iterable)`:创建迭代器。
- (3)`next(iterator,default=None)`:获取迭代器的下一个元素。
nums = [1,2,3]
it = iter(nums) # 创建迭代器
print(next(it)) # 输出:1
print(next(it)) # 输出:2
print(next(it)) # 输出:3 迭代器耗尽时,返回默认值(否则报StopIteration)
print(next(it,"结束")) # 输出:结束
7. 高阶函数类
这类函数接收函数作为参数或返回函数,是函数式编程的核心。
- (1)`map(func,*iterables)`:映射(将函数应用到每个元素)。
# 计算列表元素的平方
nums = [1,2,3]
result = map(lambda x: x*x,nums)
print(list(result)) # 输出:[1,4,9]
# 多个可迭代对象映射
a = [1,2,3]
b = [4,5,6]
result = map(lambda x,y: x+y,a,b)
print(list(result)) # 输出:[5,7,9]
- (2)`filter(func,iterable)`:过滤(保留`func`返回`True`的元素)。
# 过滤偶数
nums = [1,2,3,4,5]
result = filter(lambda x: x%2==0,nums)
print(list(result)) # 输出:[2,4]
# func为None时;保留布尔值为True的元素
result = filter(None,[0,"",1,"hello"])
print(list(result)) # 输出:[1,'hello']
- (3)`enumerate`/`sorted`:已在序列操作类中讲解,也是高阶函数。
8. 其他的常用内置函数
- (1)`help(object)`:查看对象的帮助文档。
- (2)`dir(object)`:查看对象的属性和方法。
- (3)`open(file,mode='r',encoding=None)`:打开文件(核心的IO操作)。
实战解析
【程序类别1】累加累乘
例1 计算数列 $1+\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+...+\frac{1}{n}$ 的和,n由用户输入(n≥1)。
【参考代码】
n = int(input("请输入 n 的值(n≥1):"))
if n < 1:
print("输入错误,n需≥1")
else:
sum_series = 0.0 # 用浮点数存储结果
for i in range(1,n + 1):
sum_series += 1 / i
print(f"数列前{n}项和:{sum_series:.6f}") # 保留 6 位小数
例 3 编写程序,让用户输入的一个正整数 n,计算 n 的阶乘(n!=1×2×…×n)。如果用户输入非正整数,那么提示"输入错误,请输入正整数"。
【参考代码】
n = int(input("请输入一个正整数:"))
if n <= 0:
print("输入错误,请输入正整数")
else: # 计算阶乘
factorial = 1
for i in range(1,n + 1):
factorial *= i
print(f"{n}的阶乘是:{factorial}")
【程序类别 2】文本作图
例 1 编写程序,输入金字塔的高度 n(如 n=4),打印如下所示的字母金字塔(中间是当前行对应的字母,向两边递减)。
A
ABA
ABCBA
ABCDCBA
【参考代码】
# 思路:每行 = 空格 + 递增字母 + 递减字母(去掉最后一个)
n = int(input("请输入金字塔高度:"))
for i in range(n):
# 1. 打印左侧空格
print(" " * (n - 1 - i),end="")
# 2. 打印递增字母(A 到当前字母)
for j in range(i + 1):
print(chr(65 + j),end="")
# 3. 打印递减字母(当前字母前一个到 A)
for j in range(i - 1,-1,-1):
print(chr(65 + j),end="")
# 4. 换行
print()
例 2 编写程序,打印一个高度为 5 的等腰三角形( * 为主体,空格补位)。
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
【参考代码】
# 思路:每行 = 空格 + * + 空格
# 行数 5,第 i 行(从 0 开始):空格数=4-i,* 数=2i+1
height = 5
for i in range(height): # 计算空格和 * 的数量
space = " " * (height - 1 - i)
star = "*" * (2 * i + 1)
print(space + star)
例 3 编写程序,打印一个边长为 4 的菱形( * 组成)。
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
【参考代码】
# 思路:菱形=上三角+下三角
height = 4
# 打印上三角(含中间行)
for i in range(height):
space = " " * (height - 1 - i)
star = "*" * (2 * i + 1)
print(space + star)
# 打印下三角(去掉最后一行)
for i in range(height-2,-1,-1):
space = " " * (height - 1 - i)
star = "*" * (2 * i + 1)
print(space + star)
【程序类别 3】素数
例 1 编写程序,输出 100 以内的所有质数,要求每行打印 5 个。
示例输出片段:2 3 5 7 11→下一行 13 17 19 23 29……
【参考代码】
primes = []
for num in range(2,101):
is_prime = True
for i in range(2,num): # 质数判断
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(str(num))
for i in range(0,len(primes),5): # 每行打印 5 个
print(" ".join(primes[i:i+5]))
例 2 编写函数 count_primes(start,end),接收两个正整数(start<end),返回该区间内(含两端)的质数个数,并打印所有质数。
示例:调用 count_primes(10,30)→输出 10 到 30 之间的质数有: 11 13 17 19 23 29,共 6 个。
【参考代码】
# 定义要统计的区间
start = 10
end = 30
# 存储区间内的质数
prime_list = []
# 遍历区间内的每个数,判断是否为质数
for num in range(start,end + 1):
# 基础质数判断逻辑
if num <= 1:
continue
if num == 2:
prime_list.append(num)
continue
if num % 2 == 0:
continue
# 判断奇数是否为质数(只需检查到√num)
is_prime = True
for i in range(3,int(num ** 0.5) + 1,2):
if num % i == 0:
is_prime = False
break
if is_prime:
prime_list.append(num)
# 打印结果
# 把质数列表转成字符串,用空格分隔
prime_str = " ".join(map(str,prime_list))
# 输出质数列表和个数
print(f"{start}到{end}之间的质数有:{prime_str}")
print(f"质数的总个数:{len(prime_list)}")
【程序类别 4】数列
例 1 编写函数接收参数 n,返回斐波那契数列的前 n 项。斐波那契数列的定义,第 1 项为 0,第 2 项为 1,从第 3 项开始,每一项等于前两项之和。
示例:输入 n=6,输出[0,1,1,2,3,5]。
【参考代码】
def fibonacci(n):
# 处理边界情况,n 为 0 或负数时返回空列表
if n <= 0:
return []
# n=1 时,仅返回第一个数 0
elif n == 1:
return [0]
# n=2 时,返回前两个数[0,1]
elif n == 2:
return [0,1]
# n>2 时,循环生成后续项
else:
fib_list = [0,1]
# 从第 3 项(索引 2)开始,直到第 n 项(索引 n-1)
for i in range(2,n):
# 第 i 项 = 第 i-1 项 + 第 i-2 项
next_num = fib_list[i-1] + fib_list[i-2]
fib_list.append(next_num)
return fib_list
print(fibonacci(6))
例 2 编写函数接收起始值 start、公比 ratio、项数 n,生成等比数列(允许浮点数)。若公比为 0,则返回仅包含起始值、后续全为 0 的列表;若项数为 0,则返回空列表。
示例:输入 start=2,ratio=0.5,n=4,输出[2,1.0,0.5,0.25]。
【参考代码】
def generate_geometric_sequence(start,ratio,n):
"""生成等比数列,支持浮点数和边界处理"""
if n == 0:
return []
sequence = [start] # 第一项为起始值
# 从第二项开始计算
for i in range(1,n):
current = start * (ratio ** i)
sequence.append(current)
return sequence
print(generate_geometric_sequence(2,0.5,4)) # [2,1.0,0.5,0.25]
【程序类别 5】闰年
例 编写函数接收两个整数 start_year 和 end_year(保证 start_year≤end_year),返回该区间内所有闰年的列表(包含起止年份)。
示例:输入 start_year=2000,end_year=2010,输出[2000,2004,2008]。
【参考代码】
def get_leap_years(start_year,end_year):
leap_years = []
# 遍历区间内的每一个年份
for year in range(start_year,end_year + 1):
# 闰年判断规则:
# 1. 能被 400 整除 或 2. 能被 4 整除但不能被 100 整除
if (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0):
leap_years.append(year)
return leap_years
print(get_leap_years(2000,2010)) # 输出:[2000,2004,2008]
【程序类别 6】数位分解
例 1 编写函数接收一个非负整数 num,返回一个包含该数字的每一位数字的列表(按从高位到低位的顺序)。要求输入为 0 时,返回[0],仅处理非负整数;若输入负数,则返回空列表。
示例:(1)输入 1234→输出[1,2,3,4];
(2)输入 0→输出[0];
(3)输入-567→输出[]。
【参考代码】
def extract_digits(num):
"""提取非负整数的每一位数字(高位到低位)"""
# 处理负数和非整数情况
if not isinstance(num,int) or num < 0:
return [] # 处理 0 的特殊情况
if num == 0:
return [0]
# 存储数位的列表
digits = []
# 先将数字转为字符串,遍历每个字符再转回整数
for char in str(num):
digits.append(int(char))
return digits
print(extract_digits(1234)) # [1,2,3,4]
print(extract_digits(0)) # [0]
print(extract_digits(-567)) # []
例 2 接收两个参数:整数 a(1~9)、项数 n(正整数),计算并返回 a+aa+aaa+…+(n 个 a)的值。
示例:输入 a=2,n=5,输出 24690。
【参考代码】
def compute_sum(a,n):
total = 0
current = 0
for i in range(n):
current = current * 10 + a
total += current
return total
print(compute_sum(2,5))
【程序类别 7】字典
例 1 编写函数接收一个字典 d(键为字符串,值为整数)和一个阈值 threshold,返回一个仅包含值大于 threshold 的键值对的新字典。要求不修改原字典,返回全新的字典。
示例:(1)输入 d={"math": 85,"chinese": 92,"english": 78},threshold=80 → 输出 {"math": 85,"chinese": 92};
- (2)输入 d={"a":5,"b": 3,"c": 7},threshold=7 → 输出 {"c": 7}(值等于阈值不保留)。
【参考代码】
def filter_dict_by_value(d,threshold):
"""筛选字典中值大于阈值的键值对,返回新字典"""
filtered_dict = {} # 遍历原字典的键值对
for key,value in d.items():
if value > threshold:
filtered_dict[key] = value
return filtered_dict
scores = {"math": 85,"chinese": 92,"english": 78}
print(filter_dict_by_value(scores,80)) # {'math': 85,'chinese': 92}
print(filter_dict_by_value({"a": 5,"b": 3,"c": 7},7)) # {}
例 2 有一个嵌套字典表示学生信息,其结构如下:
students = {
"001": {"name": "张三","scores": {"math": 88,"english": 90}},
"002": {"name": "李四","scores": {"math": 75,"english": 82}}}
编写函数完成以下操作,
(1)获取学号为 001 的学生的数学成绩。
(2)将学号为 002 的学生的英语成绩修改为 85。
- (3)为学号为 001 的学生新增 chinese 成绩,值为 95。
(4)返回修改后的完整字典。
【参考代码】
def update_nested_dict():
# 初始化嵌套字典
students = {
"001": {"name": "张三","scores": {"math": 88,"english": 90}},
"002": {"name": "李四","scores": {"math": 75,"english": 82}}
}
# 1. 获取 001 的数学成绩
math_score_001 = students["001"]["scores"]["math"]
print("001 的数学成绩:",math_score_001) # 输出 88
# 2. 修改 002 的英语成绩为 85
students["002"]["scores"]["english"] = 85
# 3. 为 001 新增语文成绩
students["001"]["scores"]["chinese"] = 95
# 4. 返回修改后的字典
return students
result = update_nested_dict()
print(result)
# 输出:
# {'001': {'name': '张三', 'scores': {'math': 88, 'english': 90, 'chinese': 95}},
# '002': {'name': '李四', 'scores': {'math': 75, 'english': 85}}}
【程序类别 8】函数
例 1 编写函数 calculate_average,接收任意个数的数字参数(位置可变参数),计算并返回这些数字的平均值。若没有传入参数,则返回 0,并过滤非数字类型的参数(仅计算数字的平均值)。
示例:(1)输入 1,2,3,4→输出 2.5;
- (2)输入 10,"abc",20,30→输出 20.0(仅计算 10,20,30);
(3)输入无参数→输出 0。
【参考代码】
def calculate_average(* args):
"""计算任意个数字的平均值,过滤非数字参数"""
# 筛选出数字类型的参数
numbers = []
for arg in args:
if isinstance(arg,(int,float)):
numbers.append(arg)
# 处理空列表
if not numbers:
return 0
# 计算平均值
return sum(numbers) / len(numbers)
print(calculate_average(1,2,3,4)) # 2.5
print(calculate_average(10,"abc",20,30)) # 20.0
print(calculate_average()) # 0
例 2 编写函数 calculate_bmi,接收参数 weight(体重,必传)、height(身高,必传)、unit(单位,默认值为"m",可选值有"m"和"cm")。若 unit 为"cm",则先将身高转换为"m"(除以 100),再通过 BMI(身体质量指数)公式:体重(kg)/身高²(m)计算结果,并返回保留 2 位小数的 BMI 值。若身高为 0,则返回 None。
示例:(1)输入 weight=60,height=1.75→输出 19.59;
- (2)输入 weight=60,height=175,unit="cm"→输出 19.59;
- (3)输入 weight=60,height=0→输出 None。
【参考代码】
def calculate_bmi(weight,height,unit="m"):
"""计算 BMI,支持米/厘米单位,默认米"""
# 基础校验
if not (isinstance(weight,(int,float)) and isinstance(height,(int,float))):
return None
if weight <= 0 or height <= 0:
return None
# 单位转换:厘米转米
if unit == "cm":
height = height / 100
elif unit != "m":
return None # 无效单位
# 计算 BMI 并保留 2 位小数
bmi = weight / (height ** 2)
return round(bmi,2)
print(calculate_bmi(60,1.75)) # 19.59
print(calculate_bmi(60,175,"cm")) # 19.59
print(calculate_bmi(60,0)) # None
实战演练
1. 字符串基础
编写程序,接收用户输入的一个字符串,去掉字符串两端的空格,然后输出该字符串的长度、第一个字符和最后一个字符。
2. 列表的综合操作
创建列表 nums=[12,5,8,99,34,7,12,8,99],并完成以下要求。
(1)计算列表所有元素的平均值(保留 2 位小数)。
(2)找出列表中出现次数最多的元素及其出现次数。
3. 选择结构(多条件判断)
接收用户输入的 3 个整数(代表三角形的三边长度),判断这 3 个整数能否构成三角形(任意两边之和大于第三边),若能构成,则进一步判断是等边三角形、等腰三角形,还是普通三角形;若不能构成,则输出"无法构成三角形"的最终判断结果。
4. 字典取值
定义一个字典 student={"name": "张三","age": 18,"score": 92},将该学生的分数改为"95"后输出姓名和分数。
5. 循环结构(1~100 偶数求和)
使用 while 循环计算 1 到 100(包含)之间的偶数的累加和,并输出结果。
6. 字符串拼接
接收用户输入的姓名和年龄,用两种不同的方式输出,格式为"我的名字是 XX,今年 XX 岁"。
7. 列表增、删、改
创建列表 nums=[1,2,3,4,5],并完成以下要求。
(1)在列表末尾添加元素 6。
(2)删除列表中索引为 2 的元素。
- (3)将索引为 0 的元素修改为"0",并输出修改后的列表。
8. 函数
定义一个可变参数函数 calc_average( * args),接收任意数量的数字参数,并完成以下要求。
- (1)计算并返回这些数字的平均值(若没有参数,则返回 0)。
- (2)调用该函数计算传入参数为 10,20,30 的平均值。
(3)若无传入参数,则输出所用调用结果。
9. 循环结构(打印乘法表)
使用嵌套循环打印九九乘法表的前 5 行(1×1 到 5×5)。
10. 字典+循环(词频统计)
定义字符串 text="Python is a popular programming language. Python is easy to learn, Python is powerful.",并完成以下要求。
- (1)去除字符串中的标点符号(". "和" "),将所有字母转为小写。
(2)按空格分割成单词列表。
(3)用字典统计每个单词出现的次数。
(4)输出出现次数最多的单词及其次数。
11. 递归
接收用户输入的字符串,输出该字符串的反转结果,例如:输入"abcd",输出"dcba"。
12. 列表去重
创建包含重复元素的列表 lst=[1,2,2,3,3,3,4,5,5],编写程序去除列表中的重复元素,并输出出去重后的列表。
13. 选择结构(成绩等级)
接收用户输入的 0~100 的成绩,并判断等级。 若数字超出 0~100 的范围,则提示"成绩必须在 0~100"。评判规则如下。
- (1)90~100:优秀。
- (2)80~89:良好。
- (3)70~79:中等。
- (4)60~69:及格。
- (5)0~59:不及格。
14. 字典嵌套
定义嵌套字典如下:
class_info = {
"班级": "Python 基础班",
"学生": [
{"name": "李四","age": 19},
{"name": "王五","age": 20}
]}
请输出该班级的名称,以及所有学生的姓名和年龄。
15. 循环+选择
使用 for 循环计算 1~100 的所有奇数的和,排除其中是 7 的倍数的数,并输出最终的求和结果。
16. 函数(判断素数)
定义函数 is_prime(n),使其能判断一个数是否为素数(质数),并返回 True 或 False。调用该函数判断 17 和 20 是否为素数,并输出结果。
17. 字符串切片
接收用户输入的手机号(11 位),将中间 4 位替换为 *,输出脱敏后的手机号(如 138**1234)。
18. 列表排序
创建列表 random_nums=[12,5,8,99,34,7],往列表中加入两个数后降序排序并输出。
19. 循环结构(打印空心菱形)
使用 for 循环打印如下图案。
[图:空心菱形图案]
20. 字典的增、删、改、查
定义空字典 user_info,并完成以下要求。
- (1)添加键值对:"username": "pythoner","password": "123456"。
(2)修改 password 为"654321"。
- (3)查询是否存在"email"键,不存在则添加,值为"python@test.com"。
(4)删除"username"键,并输出修改后的字典。
21. 函数+循环(阶乘计算)
定义函数 factorial(n),计算 n 的阶乘(n!=1×2×3×…×n),并调用该函数计算 5 的阶乘并输出。
22. 字符串处理(统计字符类型)
接收用户输入的字符串,统计其中的大写字母数量、小写字母数量、数字数量、其他字符数量,并输出统计结果。
23. 列表+字典(学生成绩统计)
定义列表 scores=[{"name": "赵六","语文": 88,"数学": 95,"英语": 90},{"name": "钱七","语文": 78,"数学": 82,"英语": 85},{"name": "孙八","语文": 92,"数学": 79,"英语": 94}],编写程序计算每名学生的总分,并输出每名学生的姓名和总分。
24. 循环+选择(猜数字游戏)
编写程序,系统随机生成 1~100 的整数,根据用户输入的数字给出提示,提示为"猜大了"、"猜小了"或"猜对了",最多允许猜 5 次,5 次全猜错则提示"游戏结束,正确数字是 XX"。
25. 函数(列表最大值和最小值)
定义函数 get_max_min(lst),接收一个数字列表,返回列表中的最大值和最小值(以元组形式)。调用该函数处理列表[23,56,8,77,9,45],并输出结果。
26. 字符串+循环(单词计数)
接收用户输入的一句话(以空格分隔单词),统计其中单词的数量,例如,输入"Hello Python world",输出 3。
27. 列表推导式
使用列表推导式生成 1~20 所有奇数的列表和 1~100 所有能被 7 整除的数的列表,并输出两个列表。
28. 函数+字典(成绩查询系统)
定义函数 search_score(student_dict,name),接收学生成绩字典(键为姓名,值为分数)和要查询的姓名。
(1)如果姓名存在,那么输出"XX 的成绩是 XX"。
(2)如果姓名不存在,那么输出"未找到该学生"。
- (3)测试字典为"scores_dict={"张三": 90,"李四": 85,"王五": 92}"。
29. 循环+字符串(回文判断)
编写程序,接收用户输入的字符串,判断其是否为回文字符串(正读和反读一样,如"abba""上海自来水来自海上"),并输出判断结果。
30. 综合函数(购物车结算)
定义函数 shopping_cart(cart),接收购物车字典[键为商品名称,值为(单价,数量)]。
(1)计算购物车中所有商品的总价。
(2)输出每个商品的名称、单价、数量、小计。
(3)返回总价。
- (4)测试购物车为"cart={"苹果":(5,9,2),"香蕉": (3,5,3),"橙子": (4,2,1)}"。