自学Python第10天:元组和切片——我终于搞懂了什么是“不可变的列表”

自学Python第10天:元组和切片------我终于搞懂了什么是"不可变的列表"

新手向 | 2026-07-02

昨天学了列表,能存一堆东西,还能随便增删改查,用起来很方便。

但有时候,我们并不想让数据被修改。比如一周七天,固定就是七个,不该被改动。如果用列表存,万一不小心改了其中一天,程序就会出错。

今天就来学元组 ------一个"不可变的列表",以及切片------一个能快速截取序列数据的方法。

一、元组是什么

元组和列表非常像,都是可以存放多个数据的容器。唯一的区别是:元组一旦创建,就不能修改

在 Python 里,元组用圆括号 () 表示:

python 复制代码
# 列表用方括号
fruits_list = ["苹果", "香蕉", "橙子"]

# 元组用圆括号
fruits_tuple = ("苹果", "香蕉", "橙子")

元组可以像列表一样通过下标获取数据:

python 复制代码
days = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")
print(days[0])   # 周一
print(days[-1])  # 周日

但你不能修改它:

python 复制代码
days = ("周一", "周二", "周三")
days[0] = "星期日"   # 报错!元组不支持修改

二、一个我踩过的坑:单元素元组

这个是新手很容易犯的错误。

python 复制代码
# 我想创建一个只有一个元素的元组
t = ("hello")
print(type(t))   # <class 'str'>  竟然是字符串!

你可能会想:我明明写了圆括号,为什么是字符串?

因为括号本身不是元组的标志,逗号 , 才是。 ("hello") 只是把字符串括起来了,所以类型还是字符串。加上逗号 ("hello",) 后,Python 才知道这是一个元组,举个例子:

python 复制代码
t = ("hello",)   # 注意这个逗号
print(type(t))   # <class 'tuple'>

记住:单元素元组必须加逗号。这个坑我一开始也踩过,后来记住了一条:只要想创建元组,就在末尾加个逗号,习惯之后就不会出错了。

三、元组的不可变性

元组的"不可变"体现在:不能增加、不能删除、不能修改元素。但需要注意的是,如果元组里存的是列表这种可变对象,列表本身还是可以被修改的:

python 复制代码
t = ("苹果", ["香蕉", "橙子"])
t[1].append("葡萄")   # 可以修改列表
print(t)              # ('苹果', ['香蕉', '橙子', '葡萄'])

列表可以改、元组不能改:

python 复制代码
days = ("周一", "周二", "周三")
days[0] = "星期日"   # 报错:'tuple' object does not support item assignment

这有点绕,但记住一句话就行:元组不可变,指的是元组本身的结构不变(不能增删改元素),但不限制元素内部的变化

四、什么时候用元组

场景 推荐用 原因
一周七天、一年十二个月 元组 固定不变,用元组更安全
函数返回多个值 元组 Python函数返回多个值时,默认就是元组
字典的键 元组 列表不能作为字典的键,元组可以
需要频繁增删改的数据 列表 元组不能修改

五、切片:截取序列的一部分

切片可以让你从一个序列(字符串、列表、元组)中截取一部分。

基本语法:序列起始下标:结束下标:步长

注意:切片是左闭右开的------包含起始下标,不包含结束下标。

1.基本切片

python 复制代码
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]

# 从下标0取到下标3(不包含3)
print(fruits[0:3])   # ['苹果', '香蕉', '橙子']

# 从下标1取到下标4(不包含4)
print(fruits[1:4])   # ['香蕉', '橙子', '葡萄']

# 从开头取到下标3(不包含3)
print(fruits[:3])    # ['苹果', '香蕉', '橙子']

# 从下标2取到末尾
print(fruits[2:])    # ['橙子', '葡萄', '西瓜']

注意:在元组上切片的写法完全一样:

python 复制代码
days = ("周一", "周二", "周三", "周四", "周五")
print(days[1:4])   # ('周二', '周三', '周四')

2.步长

python 复制代码
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 从0到9,步长为2(隔一个取一个)
print(numbers[0:10:2])   # [0, 2, 4, 6, 8]

# 从1到9,步长为2
print(numbers[1:10:2])   # [1, 3, 5, 7, 9]

3.负步长:反转序列

python 复制代码
numbers = [0, 1, 2, 3, 4, 5]

# 步长为负数,从右往左取
print(numbers[::-1])   # [5, 4, 3, 2, 1, 0]
print(numbers[4:1:-1]) # [4, 3, 2]

::-1是一个非常常用的写法,用来快速反转一个序列

六、字符串切片

字符串也可以切片,因为字符串本质上也是序列,举个例子:

python 复制代码
text = "Hello World"
print(text[0:5])    # Hello
print(text[6:])     # World
print(text[::-1])   # dlroW olleH(反转字符串)

七、一个我踩过的坑:切片下标越界不报错

列表下标越界会报错,但切片不会:

python 复制代码
fruits = ["苹果", "香蕉", "橙子"]
print(fruits[0:100])   # ['苹果', '香蕉', '橙子'],不报错

切片会自动忽略超出范围的索引,不会报错。这个特性有时候很方便,但如果你的切片结果为空却没有报错,可能会让调试变得困难。用切片的时候心里有数就行------如果你发现切片结果比预期短,可以检查一下是不是下标写超了。

八、综合示例:学生成绩分析

把今天学的东西串起来:

python 复制代码
# 用元组存学生姓名(固定名单,不能修改)
students = ("张三", "李四", "王五", "赵六", "孙七")

# 用列表存成绩(可以增删改)
scores = [85, 92, 78, 96, 88]

print("=== 学生成绩表 ===")
for i in range(len(students)):
    print(f"{students[i]}:{scores[i]}分")

# 用切片取出前三名
top_three = scores[:3]
print(f"\n前三名成绩:{top_three}")

# 用切片反转,查看倒数排名
scores_reversed = scores[::-1]
print(f"倒序排名成绩:{scores_reversed}")

# 字符串切片提取信息
student_info = "2024001-张三-85"
student_id = student_info[0:7]      # 2024001
name = student_info[8:10]   # 张三
score = student_info[11:]   # 85
print(f"\n学号:{student_id},姓名:{name},成绩:{score}分")

运行结果:

text 复制代码
=== 学生成绩表 ===
张三:85分
李四:92分
王五:78分
赵六:96分
孙七:88分

前三名成绩:[85, 92, 78]
倒序排名成绩:[88, 96, 78, 92, 85]

学号:2024001,姓名:张三,成绩:85分

小结

今天学的东西,整理成一张速查表:

知识点 说明 示例
定义元组 用 () 包裹数据 t = ("苹果", "香蕉")
单元素元组 必须加逗号 t = ("hello",)
元组不可变 不能增删改 t0 = "a" → 报错
列表 vs 元组 可变 vs 不可变 列表可修改,元组不可
切片 截取序列的一部分 fruits0:3
::-1 反转序列 numbers::-1
字符串切片 字符串也是序列 text0:5

什么时候用元组,什么时候用列表?

·数据固定不变(如一周七天)→ 元组

·数据需要增删 → 列表

·作为字典的键 → 元组(列表不行)

下一篇我打算学字典,这也是数据容器里非常重要的一种。

如果你也在学Python,欢迎在评论区告诉我你今天学到了什么,或者遇到了什么报错,一起交流!

相关文章: