学完了序列的基本操作,今天来认识两个重要的数据类型——列表和元组。列表就像一个可以随时加减货物的杂货铺,而元组则像一个密封的档案盒,里面的东西不能随便动。它们各有特点,用对场景能让代码更优雅!
想象你手里有一张购物清单,上面可以写水果、文具、零食,什么都能往里加,还能随时划掉某一项、修改某一项——这就是 Python 里的列表(List)。
Python 列表的特点是:
🍎 类型不限:数字、字符串、布尔值,甚至列表里再嵌套列表,都可以
✏️ 可随时修改:添加、删除、修改元素,想怎么动就怎么动
📋 有序存放:元素按顺序排列,每个位置都有对应的索引
💡 小贴士
Python 没有数组,因为列表比数组强大太多——数组只能存同一种类型,列表什么都能装,功能还更丰富。所以别纠结,直接学列表就对了!
创建列表超简单,把元素全部塞进方括号 [] 里,元素之间用逗号隔开就行。
# 购物清单shopping_list = ['牛奶', '面包', '鸡蛋', '苹果']# 混合类型的列表mixed_data = [1024, 0.5, 'Python', True]# 空列表empty_list = []print(shopping_list)# ['牛奶', '面包', '鸡蛋', '苹果']
💡 小贴士
空列表很有用,比如先建个空盒子,之后再往里装东西。用 [] 或 list() 都能创建空列表。
和字符串一样,列表也用索引来访问元素。正向索引从 0 开始,负向索引从 -1 开始表示倒数第一个。
fruits = ['苹果', '香蕉', '橘子', '葡萄', '西瓜']# 单个索引访问print(fruits[0]) # 苹果print(fruits[-1]) # 西瓜# 切片访问print(fruits[1:3]) # ['香蕉', '橘子']print(fruits[2:]) # ['橘子', '葡萄', '西瓜']
⚠️ 踩坑经验
索引超范围会报 IndexError!比如列表只有 5 个元素(索引 0-4),访问 fruits[5] 就会报错。写循环时特别注意边界!
列表最强大的地方就是可以随时修改。可以直接给某个位置赋值,也可以用 append() 在末尾添加新元素。
scores = [85, 92, 78, 90]# 修改某个元素scores[2] = 88print(scores) # [85, 92, 88, 90]# 末尾添加元素scores.append(95)print(scores) # [85, 92, 88, 90, 95]# 在指定位置插入scores.insert(1, 80)print(scores) # [85, 80, 92, 88, 90, 95]
💡 小贴士
append() 是在末尾加一个元素,insert() 可以在任意位置插入。如果想在列表末尾一次性加入多个元素,用 extend() 或直接 list_a + list_b。
删元素有三种方式:del 按索引删、remove() 按值删、pop() 删并返回。
tasks = ['起床', '吃早餐', '上班', '开会', '下班']# del 按索引删除del tasks[2]print(tasks) # ['起床', '吃早餐', '开会', '下班']# remove 按值删除(删第一个匹配项)tasks.remove('开会')print(tasks) # ['起床', '吃早餐', '下班']# pop 删除末尾并返回done = tasks.pop()print(f'已完成: {done}') # 已完成: 下班print(tasks) # ['起床', '吃早餐']
⚠️ 踩坑经验
remove() 删除的是第一个匹配项,如果元素不存在会报错。如果有重复元素想全删,得用循环!
列表自带了很多好用的方法,下面按功能分类介绍:
统计类方法
grades = ['A', 'B', 'A', 'C', 'B', 'A']# count() - 统计元素出现次数print(grades.count('A')) # 3# index() - 查找元素首次出现的索引print(grades.index('B')) # 1print(grades.index('C')) # 3
排序与复制
prices = [88, 45, 120, 33, 76]# sort() - 原地排序(修改原列表)prices.sort()print(prices) # [33, 45, 76, 88, 120]# 降序排列prices.sort(reverse=True)print(prices) # [120, 88, 76, 45, 33]# copy() - 复制列表(浅拷贝)prices_backup = prices.copy()print(prices_backup) # [120, 88, 76, 45, 33]
💡 小贴士
sort() 会直接修改原列表,如果想保留原顺序,用 sorted() 内置函数返回新列表。
💡 小贴士
复制列表用 copy() 而不是直接赋值 b = a,后者只是创建了一个引用,修改 b 也会影响到 a!
如果说列表是可变的"购物清单",那元组就是不可变的"档案袋"。一旦装进去,你就不能随便往里塞东西、也不能划掉东西——里面的内容是固定的。
元组的特点:
🔒 不可修改:创建后不能添加、删除、修改元素
⚡ 性能更好:因为不可变,Python 做了优化,访问速度比列表快
🔑 可作为字典键:元组可以作为字典的 key,列表不行
💡 小贴士
什么时候用元组?当你的数据是"写死的"、不需要修改时。比如一年十二个月的英文简称、一周的星期几、GPS 坐标等,用元组更安全也更快。
元组用圆括号 () 来创建,元素之间用逗号隔开。如果只有一个元素,后面也要加逗号,不然会被当成普通括号表达式。
# 课程表元组courses = ('语文', '数学', '英语', '物理', '化学')# 单个元素的元组(必须加逗号)single = ('苹果',)print(type(single)) ## 不用括号也可以(逗号分隔就是元组)coordinates = 40.7128, -74.0060print(coordinates) # (40.7128, -74.006)
⚠️ 踩坑经验
写单个元素的元组一定要加逗号!('苹果') 只是字符串加了个括号,不是元组,('苹果',) 才是元组!
元组的访问方式和列表一模一样,用索引和切片都能正常用。因为元组只是不能修改,读取是完全没问题的。
weekdays = ('周一', '周二', '周三', '周四', '周五', '周六', '周日')# 单个访问print(weekdays[0]) # 周一print(weekdays[-1]) # 周日# 切片访问print(weekdays[0:5]) # ('周一', '周二', '周三', '周四', '周五')print(weekdays[5:]) # ('周六', '周日')
元组一旦创建,就真的不能改。如果硬要"改",只能重新创建一个新的元组覆盖原来的变量。这不是真正的修改,而是重新赋值。
dimensions = (800, 600)# 不能这样改:dimensions[0] = 1024 # TypeError!# 只能重新赋值整个元组dimensions = (1024, 768)print(dimensions) # (1024, 768)# 或者用拼接创建新元组new_dimensions = dimensions + (300,)print(new_dimensions) # (1024, 768, 300)
⚠️ 踩坑经验
元组里的列表元素是可以修改的!比如 t = ([1,2], [3,4]),元组本身不能改,但里面的列表可以改。这叫"浅不可变",小心别踩坑!
元组里的单个元素不能删,但可以删整个元组变量。如果想清空内容,重新赋值为空元组就行。
config = ('localhost', 8080, True)# 不能删单个元素:del config[0] # TypeError!# 可以删整个元组del config# print(config) # NameError: name 'config' is not defined# 如果只是想让元组变空,赋值为空元组empty_config = ()print(empty_config) # ()
因为元组不可变,所以方法比列表少很多,但常用的几个还是有的:
letters = ('d', 'b', 'a', 'f', 'd')# count() - 统计元素出现次数print(letters.count('d')) # 2# index() - 查找元素首次出现的索引print(letters.index('a')) # 2# len() - 计算元素个数(内置函数)print(len(letters)) # 5# max() / min() - 最大最小值print(max(letters)) # fprint(min(letters)) # a
类型转换
# 列表转元组shopping_list = ['牛奶', '面包', '鸡蛋']frozen_list = tuple(shopping_list)print(frozen_list) # ('牛奶', '面包', '鸡蛋')# 元组转列表fresh_list = list(frozen_list)fresh_list.append('水果')print(fresh_list) # ['牛奶', '面包', '鸡蛋', '水果']
💡 小贴士
tuple() 和 list() 可以互相转换,但转换后会创建新对象,之前的对象保持不变。
很多新手纠结到底用列表还是元组,下面这张表帮你做决策:
💡 小贴士
记住一个原则:能用元组就别用列表。元组更安全、更快,只有当数据确实需要修改时才用列表。这是一种编程习惯的优化。
⚠️ 踩坑经验
返回多个值时 Python 实际返回的是元组!比如 return x, y 其实是返回 return (x, y)。这是元组最常见的"隐形"用法!
列表和元组是 Python 中最常用的数据结构。列表灵活多变,适合需要频繁修改的场景;元组安全高效,适合固定不变的数据。理解它们的区别和适用场景,能让你的代码更优雅、更高效!