Python 函数、列表与元组核心用法及实战解析
作为 Python 初学者,掌握函数、列表、元组是从'写代码'到'写好代码'的关键一步。它们不仅是语法的核心,更是后续处理复杂数据、构建高效程序的基础。本文将结合实战案例,把这三个知识点讲透。
一、函数:告别重复代码的'工厂'
1.1 为什么需要函数?
写代码最忌讳的就是'复制粘贴'。比如计算不同区间的数列和(1-100、300-400),如果不使用函数,需要重复写多组几乎一样的循环代码:
# 原始写法:重复且难以维护
theSum = 0
for i in range(1, 101):
theSum = theSum + i
print(theSum)
theSum = 0
for i in range(300, 401):
theSum = theSum + i
print(theSum)
一旦需要修改计算逻辑(比如改成求平方和),所有重复代码都要改。而函数的核心作用,就是提取重复代码,实现复用,让程序更简洁、更好维护。
简单理解:函数就像一个'工厂',输入'原材料'(参数),经过内部加工(函数体),输出'产品'(返回值),一次定义,多次调用。
# 优化后的函数版本
def calc_sum(begin, end):
the_sum = 0
for i in range(begin, end + 1):
the_sum += i
print(the_sum)
# 调用函数
calc_sum(1, 100)
calc_sum(300, 400)
calc_sum(1, 1000)
1.2 函数的核心语法
(1)定义与调用
# 定义函数:def 函数名 (形参列表): 函数体 return 返回值
def calc_sum(beg, end):
# beg、end 是'形式参数',相当于工厂的'原材料入口'
total = 0
for i in range(beg, end + 1):
total += i
return total # return 输出结果,相当于工厂的'产品出口'
# 调用函数:函数名 (实参列表)
result1 = calc_sum(1, 100) # 1、100 是'实际参数'
result2 = calc_sum(300, 400)
print(result1, result2) # 输出:5050 35150
⚠️ 关键注意点:
- 函数必须先定义,再调用,否则会报
NameError。 - 定义时不会执行函数体,只有调用时才执行。
- 形参和实参的个数必须匹配,否则报
TypeError。
(2)参数的灵活用法
Python 的参数机制比 C++、Java 更灵活,核心有 3 个特性:
- 动态类型:形参无需指定类型,一个函数可接收多种类型参数。
def print_param(a):
print(a)
print_param(10) # 整数
print_param("hello") # 字符串
print_param(True) # 布尔值
- 默认参数:给形参设置默认值,调用时可省略该参数。注意:默认值参数必须在无默认值参数后面。
# 计算两数之和,默认不打印调试信息
def add(x, y, debug=False):
if debug:
print(f"调试:x={x}, y={y}")
return x + y
print(add(10, 20)) # 省略 debug,使用默认值 False
print(add(10, 20, True)) # 显式传参,打印调试信息
- 关键字参数:调用时显示指定'实参对应哪个形参',可打乱传参顺序。
def test(x, y):
print(f"x = {x}")
print(f"y = {y}")
# 关键字参数,顺序无关
test(x=10, y=20)
test(y=100, x=200)
(3)返回值与变量作用域
返回值:一个函数可以有多个 return 语句,执行到 return 时函数立刻结束。支持一次返回多个值(用逗号分隔)。
def get_point():
x = 10
y = 20
return x, y # 返回两个值
# 接收返回值
_, b = get_point() # 忽略 x,只接收 y
变量作用域:决定了变量能在哪些地方使用。
- 局部变量:函数内部定义,仅在函数内生效。
- 全局变量:函数外部定义,函数内可访问,但修改时需要用
global声明。
x = 10 # 全局变量
def test():
global x
x = 20 # 修改全局变量需声明
test()
print(f"x = {x}") # 输出 20
1.3 进阶用法:嵌套与递归
链式调用:把一个函数的返回值,作为另一个函数的参数。
def is_odd(num):
return num % 2 == 0
def add(x, y):
return x + y
# 嵌套调用
print(is_odd(add(5, 5))) # 先加后判断奇偶
递归调用:函数调用自身。核心是'有结束条件 + 每次逼近结束条件',否则会无限递归导致 RecursionError。
# 递归计算 n 的阶乘
def factor(n):
if n == 1: # 结束条件
return 1
return n * factor(n - 1)
print(factor(5)) # 输出 120
⚠️ 注意:递归代码简洁但难理解,易栈溢出,实际开发中优先用循环替代。
二、列表和元组:批量存储数据的'容器'
当需要存储多个数据(比如 10 个学生的成绩)时,单独定义多个变量不现实。此时就需要列表(list)和元组(tuple)——它们是 Python 中最常用的'序列类型'。
核心区别:
- 列表(list):可变容器,元素可增删改。
- 元组(tuple):不可变容器,元素创建后无法修改。
2.1 列表(list):最常用的可变容器
(1)创建列表
推荐直接使用 [ ],更简洁。
a = [] # 空列表
b = list() # 使用构造函数
c = [1, 2, 3, 4] # 带初始值
d = [1, 'hello', True] # 混合类型
⚠️ 注意:不要用 list 作为变量名,这会覆盖内置函数 list()。
(2)核心操作
列表的操作都围绕'下标'展开,下标从 0 开始(负数表示倒数,-1 是最后一个元素)。
| 操作目的 | 代码示例 | 说明 |
|---|---|---|
| 访问元素 | list[2] | 访问下标 2 的元素,越界报 IndexError |
| 修改元素 | list[2] = 100 | 修改指定位置的值 |
| 切片 | list[1:3] | 取下标 1 到 3(左闭右开) |
| 新增元素 | append() / insert() | 尾插或指定位置插入 |
| 删除元素 | pop() / remove() | 按索引或按值删除 |
| 查找元素 | in / index() | 判断存在性或获取下标 |
| 连接列表 | + / extend() | 拼接列表 |
# 下标访问与修改
a = [1, 2, 3, 4]
print(a[2]) # 3
a[2] = 100
print(a[-1]) # 4 (倒数第一个)
# 遍历
for elem in a:
print(elem)
# 增删查改
a.append(5) # 末尾添加
a.pop() # 删除末尾
a.remove(2) # 删除值为 2 的元素
(3)切片操作的灵活用法
切片是列表的'灵魂操作',支持省略边界、指定步长。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
# 基本切片
print(a[1:3]) # [2, 3]
# 省略边界
print(a[1:]) # 从 1 取到结尾
print(a[:2]) # 从开头取到 2
print(a[:]) # 复制整个列表
# 步长
print(a[::2]) # 每隔一个取一个
print(a[::-1]) # 反转列表
2.2 元组(tuple):不可变的序列容器
元组的用法和列表几乎一致,但核心区别是'不可变'。适合存储不需要修改的数据(比如身份证号、坐标)。
# 创建元组
a = () # 空元组
b = (1, 2, 3) # 带值
single = (1,) # 单个元素必须加逗号
# 支持读操作
print(b[0]) # 1
print(b[1:3]) # (2, 3)
# 不支持写操作
# b[0] = 100 # 报错 TypeError
# b.append(4) # 报错 AttributeError
为什么有了列表还需要元组?
- 安全性:传递数据时,用元组可避免数据被意外修改。
- 字典键:字典的键必须是'可哈希对象'(不可变类型),元组可以,列表不行。
2.3 小结
| 特性 | 列表(list) | 元组(tuple) |
|---|---|---|
| 定义方式 | [] | () |
| 是否可变 | 可变 | 不可变 |
| 适用场景 | 需频繁修改数据 | 数据无需修改 |
| 核心操作 | 增删改查 | 仅读操作 |
在需要表示一个'序列'的场景下,就可以考虑使用列表和元组。如果元素不需要改变,则优先考虑元组;如果需要改变,则优先考虑列表。
结语
掌握函数、列表与元组,意味着你掌握了 Python 编程的基石。函数让逻辑清晰复用,列表与元组让数据处理游刃有余。在实际开发中,根据数据是否需要修改来选择合适的容器,能让你的代码更加健壮。


