Python 从入门到实战(三):列表与元组(批量管理数据的 “容器”)

举报
倔强的石头_ 发表于 2025/12/09 15:20:00 2025/12/09
【摘要】 本文介绍了Python中列表(List)和元组(Tuple)的基本概念与核心操作。列表是可修改的数据容器,通过方括号[]定义,支持元素的增删改查;元组是不可修改的容器,用圆括号()定义。文章详细讲解了列表的创建、索引访问、元素修改(append/insert/extend)、删除(del/pop/remove)等操作,并比较了sort()与sorted()排序方法的区别。

c6e3154d215982a75f2280a6ca6650b4.jpeg

欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们掌握了变量和数据类型,能处理单个数据(比如一个人的名字、年龄)。但实际场景中,我们经常需要处理多个数据—— 比如一个人的多个爱好、一个班级的学生名单、一组商品价格。这时候,用单个变量存储就太麻烦了(总不能用 hobby1、hobby2、hobby3 吧?)。

今天咱们要学 Python 中最常用的 “数据容器”:列表(List) 和元组(Tuple)。列表就像 “可修改的抽屉”,能随时添加、删除、调整里面的东西;元组则像 “带锁的抽屉”,里面的东西一旦放进去就不能改。学会它们,你就能轻松批量管理多个数据,为后面的循环操作打基础。

一、先搞懂:为什么需要列表?

咱们从一个实际场景切入:假设你要存储自己的 5 个爱好,用之前学的变量怎么处理?

python

运行

# 用单个变量存储多个爱好(麻烦!)
hobby1 = "篮球"
hobby2 = "编程"
hobby3 = "阅读"
hobby4 = "跑步"
hobby5 = "做饭"

# 打印所有爱好(要写5行print,太繁琐)
print(hobby1)
print(hobby2)
print(hobby3)
print(hobby4)
print(hobby5)

如果要添加一个爱好,还得再定义 hobby6;要删除一个,还得删对应的变量 —— 这显然不灵活。

而用列表,一行代码就能存储所有爱好,后续修改也很方便:

python

运行

# 用列表存储多个爱好(简洁!)
hobbies = ["篮球", "编程", "阅读", "跑步", "做饭"]

# 打印所有爱好(一行代码搞定)
print(hobbies)  # 输出:['篮球', '编程', '阅读', '跑步', '做饭']

这就是列表的核心作用:把多个同类型(或相关)的数据集中存储,方便批量管理。接下来,咱们从列表的基本用法开始,一步步掌握它的全部技能。

二、列表:可修改的 “数据抽屉”(核心操作)

列表在 Python 中用方括号[] 定义,元素之间用逗号分隔,比如[元素1, 元素2, 元素3]。它的操作非常灵活,咱们按 “访问→修改→管理” 的顺序讲解,每个操作都配具体场景和示例。

1. 列表的基本操作:创建与访问元素

▶ 第一步:创建列表

创建列表很简单,用方括号包裹元素即可。元素可以是任意数据类型(字符串、数字、甚至后面会学的字典),但建议存储同类型数据(比如都是爱好、都是学生名),方便后续处理。

python

运行

# 示例1:存储字符串列表(爱好)
hobbies = ["篮球", "编程", "阅读"]

# 示例2:存储数字列表(成绩)
scores = [95, 88, 92, 79]

# 示例3:存储混合类型(不推荐,除非有特殊需求)
mixed_list = ["张三", 18, 90.5]

# 打印列表(会显示方括号和逗号,这是列表的默认格式)
print(hobbies)  # 输出:['篮球', '编程', '阅读']
print(scores)   # 输出:[95, 88, 92, 79]

▶ 第二步:访问列表元素(重点:索引规则)

要获取列表中的某个元素,需要用索引(元素在列表中的 “位置编号”)。Python 中列表的索引有两个关键规则,新手必须牢记:

  1. 索引从 0 开始:第一个元素索引是 0,第二个是 1,以此类推;
  2. 负索引表示从末尾开始:-1 是最后一个元素,-2 是倒数第二个,以此类推(不用记列表长度,很方便)。

示例代码:

python

运行

# 定义一个水果列表
fruits = ["苹果", "香蕉", "橙子", "葡萄"]

# 1. 用正索引访问
print(f"第一个水果:{fruits[0]}")  # 输出:第一个水果:苹果(索引0)
print(f"第三个水果:{fruits[2]}")  # 输出:第三个水果:橙子(索引2)

# 2. 用负索引访问
print(f"最后一个水果:{fruits[-1]}")  # 输出:最后一个水果:葡萄(负索引-1)
print(f"倒数第二个水果:{fruits[-2]}")  # 输出:倒数第二个水果:橙子(负索引-2)

# 3. 结合字符串方法(比如首字母大写)
print(f"格式化输出:{fruits[1].title()}")  # 输出:格式化输出:香蕉

▶ 新手必踩坑:避免索引错误

如果访问的索引超出列表范围(比如列表只有 4 个元素,访问索引 4),Python 会报IndexError(索引错误)。这是新手最常见的错误之一,咱们看示例并学习如何排查:

python

运行

# 错误示例:列表只有4个元素,索引最大是3
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print(fruits[4])  # 报错:IndexError: list index out of range

# 排查方法:
# 1. 先打印列表,确认元素数量
print(fruits)  # 输出:['苹果', '香蕉', '橙子', '葡萄'](4个元素)
# 2. 用len()函数查看列表长度(元素个数)
print(len(fruits))  # 输出:4(说明索引范围是0~3)
# 3. 用负索引访问末尾元素(不用记长度)
print(fruits[-1])  # 输出:葡萄(安全,不会报错)

2. 列表元素的修改、添加与删除(高频操作)

列表的核心优势是 “可修改”—— 能随时调整里面的元素。咱们分 “修改已有元素”“添加新元素”“删除不需要的元素” 三类场景讲解,每个场景给具体方法和示例。

▶ 场景 1:修改已有元素(按索引赋值)

如果要修改列表中的某个元素,直接通过 “列表名 [索引] = 新值” 赋值即可。

python

运行

# 定义一个学生名单列表
students = ["张三", "李四", "王五"]

# 修改第二个学生(索引1)的名字
students[1] = "李华"

# 打印修改后的列表
print(students)  # 输出:['张三', '李华', '王五']

# 实际应用:修改成绩(把79改成85)
scores = [95, 88, 79, 92]
scores[2] = 85
print(scores)  # 输出:[95, 88, 85, 92]

▶ 场景 2:添加新元素(3 种方法)

根据添加位置的不同,有 3 种常用方法:

  1. append(元素):在列表末尾添加元素(最常用,效率最高);
  2. insert(索引, 元素):在指定索引位置添加元素(会把后面的元素 “挤” 到后面);
  3. extend(列表):把另一个列表的所有元素添加到当前列表末尾(批量添加)。

示例代码:

python

运行

# 定义一个购物车列表
shopping_cart = ["牛奶", "面包"]

# 1. append():在末尾添加“鸡蛋”
shopping_cart.append("鸡蛋")
print("添加鸡蛋后:", shopping_cart)  # 输出:添加鸡蛋后:['牛奶', '面包', '鸡蛋']

# 2. insert():在索引0的位置添加“苹果”(开头添加)
shopping_cart.insert(0, "苹果")
print("添加苹果后:", shopping_cart)  # 输出:添加苹果后:['苹果', '牛奶', '面包', '鸡蛋']

# 3. extend():批量添加“酸奶”和“饼干”(用另一个列表)
other_items = ["酸奶", "饼干"]
shopping_cart.extend(other_items)
print("批量添加后:", shopping_cart)  # 输出:批量添加后:['苹果', '牛奶', '面包', '鸡蛋', '酸奶', '饼干']

▶ 场景 3:删除元素(4 种方法,按需选择)

删除元素的方法有很多,关键是根据 “是否知道索引”“是否需要保留删除的元素” 来选择:

方法 适用场景 是否需要知道索引 是否保留删除的元素
del 列表[索引] 彻底删除,后续不用这个元素
列表.pop() 删除末尾元素,且后续需要用这个元素 否(固定删末尾)
列表.pop(索引) 删除指定索引元素,且后续需要用这个元素
列表.remove(值) 不知道索引,只知道要删除的 “值”

示例代码:

python

运行

# 定义一个待办事项列表
todo_list = ["写代码", "买咖啡", "开会", "整理文档"]

# 1. del:删除“买咖啡”(索引1),后续不用这个元素
del todo_list[1]
print("删除买咖啡后:", todo_list)  # 输出:删除买咖啡后:['写代码', '开会', '整理文档']

# 2. pop():删除末尾的“整理文档”,并打印出来(后续要用)
deleted_item = todo_list.pop()
print("删除的元素:", deleted_item)  # 输出:删除的元素:整理文档
print("pop后列表:", todo_list)     # 输出:pop后列表:['写代码', '开会']

# 3. pop(索引):删除“开会”(索引1),并打印
deleted_item2 = todo_list.pop(1)
print("删除的元素2:", deleted_item2)  # 输出:删除的元素2:开会
print("pop(1)后列表:", todo_list)    # 输出:pop(1)后列表:['写代码']

# 4. remove():删除“写代码”(只知道值,不知道索引)
todo_list.remove("写代码")
print("remove后列表:", todo_list)    # 输出:remove后列表:[]

# 注意:remove()只删除第一个匹配的值
numbers = [1, 2, 3, 2, 4]
numbers.remove(2)
print("remove(2)后:", numbers)  # 输出:remove(2)后:[1, 3, 2, 4](只删了第一个2)

3. 列表管理:排序、反转与统计(批量处理)

当列表元素较多时,需要批量管理(比如排序、统计个数),Python 提供了现成的方法,不用自己写复杂逻辑。

▶ 方法 1:排序(sort()永久排序 vs sorted()临时排序)

  • 列表.sort():对列表进行永久排序(列表本身会变,无法恢复);
  • sorted(列表):对列表进行临时排序(返回排序后的新列表,原列表不变);
  • 两者都支持reverse=True参数,实现 “倒序排序”。

示例代码:

python

运行

# 定义一个数字列表
numbers = [3, 1, 4, 2, 5]

# 1. sort():永久排序(正序)
numbers.sort()
print("sort()正序后:", numbers)  # 输出:sort()正序后:[1, 2, 3, 4, 5]

# 2. sort(reverse=True):永久倒序
numbers.sort(reverse=True)
print("sort()倒序后:", numbers)  # 输出:sort()倒序后:[5, 4, 3, 2, 1]

# 3. sorted():临时排序(原列表不变)
original_numbers = [3, 1, 4, 2, 5]
sorted_numbers = sorted(original_numbers)
print("原列表:", original_numbers)  # 输出:原列表:[3, 1, 4, 2, 5](不变)
print("sorted()结果:", sorted_numbers)  # 输出:sorted()结果:[1, 2, 3, 4, 5]

# 4. sorted(reverse=True):临时倒序
reverse_sorted = sorted(original_numbers, reverse=True)
print("sorted()倒序:", reverse_sorted)  # 输出:sorted()倒序:[5, 4, 3, 2, 1]

▶ 方法 2:反转列表(reverse()

列表.reverse()永久反转列表的元素顺序(不是排序,只是倒过来),示例:

python

运行

# 定义一个列表
fruits = ["苹果", "香蕉", "橙子"]

# 反转列表
fruits.reverse()
print("反转后:", fruits)  # 输出:反转后:['橙子', '香蕉', '苹果']

# 再次反转,恢复原顺序
fruits.reverse()
print("再次反转后:", fruits)  # 输出:再次反转后:['苹果', '香蕉', '橙子']

▶ 方法 3:统计列表长度(len()

len(列表)会返回列表的元素个数(整数),常用于判断列表是否为空、统计数据量。

python

运行

# 定义一个学生列表
students = ["张三", "李四", "王五"]

# 统计学生人数
student_count = len(students)
print(f"学生总数:{student_count}人")  # 输出:学生总数:3人

# 实际应用:判断列表是否为空(比如购物车是否有商品)
shopping_cart = []
if len(shopping_cart) == 0:
    print("购物车是空的,请添加商品!")  # 输出:购物车是空的,请添加商品!

三、元组:不可修改的 “固定容器”(场景与用法)

有时候,我们需要存储固定不变的数据(比如矩形的长和宽、一周的天数),这时候用列表就有风险 —— 万一不小心修改了数据,会导致错误。Python 提供了 “不可修改的列表”——元组(Tuple),正好解决这个问题。

1. 元组的定义:用圆括号,不可修改

元组用圆括号() 定义,元素之间用逗号分隔。它的用法和列表类似,但有一个核心区别:元组创建后,元素不能修改(不能添加、删除、修改值)。

python

运行

# 示例1:定义一个元组(存储矩形的长和宽)
rectangle = (10, 5)

# 访问元组元素(和列表一样,用索引)
print(f"矩形的长:{rectangle[0]}")  # 输出:矩形的长:10
print(f"矩形的宽:{rectangle[1]}")  # 输出:矩形的宽:5

# 错误示例:尝试修改元组元素(会报错)
rectangle[0] = 15  # 报错:TypeError: 'tuple' object does not support item assignment

# 示例2:定义只有一个元素的元组(必须加逗号,否则会被当作普通数据)
single_tuple = (3,)  # 正确:加逗号,是元组
not_tuple = (3)      # 错误:不加逗号,是整数
print(type(single_tuple))  # 输出:<class 'tuple'>(元组类型)
print(type(not_tuple))      # 输出:<class 'int'>(整数类型)

2. 元组的适用场景:存储固定数据

元组的 “不可修改” 是优势,适合存储 “不会变的数据”,比如:

  • 固定配置(比如窗口大小、颜色值);
  • 批量常量(比如一周的 7 天、一年的 12 个月);
  • 函数返回的多个值(后面学函数会用到)。

示例代码:

python

运行

# 场景1:存储一周的天数(固定不变)
week_days = ("周一", "周二", "周三", "周四", "周五", "周六", "周日")

# 遍历元组(和列表一样,用for循环)
for day in week_days:
    print(day)  # 依次输出周一到周日

# 场景2:存储窗口配置(宽、高、背景色)
window_config = (800, 600, "white")
width, height, bg_color = window_config  # 批量赋值
print(f"窗口宽:{width},高:{height},背景色:{bg_color}")  # 输出:窗口宽:800,高:600,背景色:white

3. 元组的 “修改”:重新赋值整个元组

虽然元组的元素不能修改,但可以重新赋值整个元组(相当于替换掉原来的 “固定容器”)。

python

运行

# 定义一个元组(旧的窗口配置)
window_config = (800, 600)
print("旧配置:", window_config)  # 输出:旧配置:(800, 600)

# 重新赋值整个元组(新的窗口配置)
window_config = (1024, 768)
print("新配置:", window_config)  # 输出:新配置:(1024, 768)

四、综合实操:管理 “学生成绩表”

咱们结合今天学的列表和元组知识,做一个 “学生成绩表” 程序,实现以下功能:

  1. 用列表存储学生姓名和对应的成绩;
  2. 添加新学生和成绩;
  3. 删除成绩不合格的学生(低于 60 分);
  4. 对成绩进行排序,显示排名;
  5. 用元组存储成绩等级标准(比如 60 分及格、80 分优秀)。

完整代码:

python

运行

# 学生成绩表管理程序
print("===== 学生成绩表管理 =====")

# 1. 初始化学生成绩列表(每个元素是“姓名-成绩”的小列表)
student_scores = [["张三", 85], ["李四", 72], ["王五", 58], ["赵六", 93]]

# 2. 添加新学生(张三的成绩)
new_student = ["孙七", 88]
student_scores.append(new_student)
print("添加新学生后:")
for name, score in student_scores:
    print(f"{name}{score}分")

# 3. 删除成绩不合格的学生(低于60分)
# 注意:遍历列表时不能直接删除,所以先创建一个新列表存储合格学生
qualified_students = []
for name, score in student_scores:
    if score >= 60:
        qualified_students.append([name, score])
student_scores = qualified_students  # 替换为合格学生列表
print("\n删除不合格学生后:")
for name, score in student_scores:
    print(f"{name}{score}分")

# 4. 对成绩排序(按成绩降序)
# 用sort(),key参数指定按“成绩”排序(列表的第二个元素,索引1)
student_scores.sort(key=lambda x: x[1], reverse=True)
print("\n按成绩降序排名:")
for i, (name, score) in enumerate(student_scores, start=1):  # enumerate()获取排名
    print(f"第{i}名:{name}{score}分")

# 5. 用元组存储成绩等级标准,判断每个学生的等级
grade_standard = (60, 80, 90)  # 60及格,80良好,90优秀
print("\n成绩等级评定:")
for name, score in student_scores:
    if score >= grade_standard[2]:
        grade = "优秀"
    elif score >= grade_standard[1]:
        grade = "良好"
    elif score >= grade_standard[0]:
        grade = "及格"
    else:
        grade = "不及格"  # 这里其实不会出现,因为已经删除不合格学生
    print(f"{name}{score}分,等级:{grade}")

print("======================")

运行结果:

plaintext

===== 学生成绩表管理 =====
添加新学生后:
张三:85分
李四:72分
王五:58分
赵六:93分
孙七:88分

删除不合格学生后:
张三:85分
李四:72分
赵六:93分
孙七:88分

按成绩降序排名:
第1名:赵六,93分
第2名:孙七,88分
第3名:张三,85分
第4名:李四,72分

成绩等级评定:
赵六:93分,等级:优秀
孙七:88分,等级:良好
张三:85分,等级:良好
李四:72分,等级:及格
======================

五、列表与元组的核心区别(总结表)

为了让大家更清晰地选择 “该用列表还是元组”,这里整理了两者的核心区别:

特性 列表(List) 元组(Tuple)
定义符号 方括号 [] 圆括号 ()
是否可修改 是(添加、删除、修改元素) 否(元素不可变,可重新赋值)
适用场景 存储可变数据(如购物车、待办) 存储固定数据(如配置、常量)
常用方法 append ()、sort ()、pop () 等 无(只有 count ()、index () 等基础方法)
性能 修改快,遍历稍慢 遍历快,占用内存少

六、小结与下一篇预告

这篇你学到了什么?

  1. 列表:用[]定义,可修改的 “数据容器”,掌握了访问(索引规则)、修改 / 添加 / 删除元素(按需选方法)、管理(排序、反转、统计);
  2. 元组:用()定义,不可修改的 “固定容器”,适合存储不变数据,可重新赋值整个元组;
  3. 核心区别:列表可变(灵活),元组不可变(安全、高效),根据数据是否需要修改选择。

下一篇预告

今天咱们学了 “存储多个数据的容器”,但要批量处理这些数据(比如遍历所有学生成绩、计算平均分),还需要 “循环”—— 这是 Python 自动化处理的核心。下一篇咱们会学for循环和while循环,教你用几行代码搞定大量数据的重复操作,让程序真正 “自动化” 起来。

如果这篇内容帮你搞定了列表和元组,欢迎在评论区分享你的 “学生成绩表” 改进版本(比如添加 “计算平均分” 功能),咱们一起交流进步~

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。