5.1 列表 —— Python 里的"万能收纳盒"
如果说变量是一个小抽屉,那列表就是一个大收纳盒——可以把各种东西放进去,随时取用、随意增减、还能排序整理。列表是 Python 中最灵活、最常用的数据类型。
🎯 本节要点:掌握列表的创建、访问、添加、排序、删除和列表推导式
🔗 关联小程序: ch05_s5_1
一、什么是列表?
列表(list)是 Python 中最核心的组合数据类型。简单说,它就是用方括号装起来的一组数据。
# 各种列表的例子empty_list = [] # 空列表names = ['小明', '小红', '小兰'] # 字符串列表mixed = [1, 'a', 2.5, True] # 混合类型列表nested = [1, 2, [3, 4]] # 嵌套列表(列表里的列表)
列表的核心特征:
创建列表的两种方式
# 方式 1:用方括号直接创建list_one = [] # 空列表list_two = ['p', 'y', 't', 'h', 'o', 'n']list_three = [1, 'a', '&', 2.3] # 不同类型混装list_four = [1, 'a', '&', 2.3, list_three] # 嵌套列表# 方式 2:用 list() 函数创建li_one = list() # 空列表,结果为 []li_two = list('python') # 根据字符串创建,结果为 ['p', 'y', 't', 'h', 'o', 'n']li_three = list([1, 'python']) # 根据其他列表创建
可迭代对象——list() 的参数
几乎所有可以"挨个取出元素"的东西,都能传给 list():
# 字符串 → 拆成字符列表print(list('hello')) # ['h', 'e', 'l', 'l', 'o']# range() → 转为数字列表print(list(range(5))) # [0, 1, 2, 3, 4]# 元组 → 转为列表print(list((1, 2, 3))) # [1, 2, 3]
💡 小知识:列表是一个典型的"可迭代对象"(iterable)。判断一个对象是否可迭代,可以用 isinstance():
from collections.abc import Iterableprint(isinstance([1, 2, 3], Iterable)) # Trueprint(isinstance('abc', Iterable)) # Trueprint(isinstance(123, Iterable)) # False
二、访问列表元素
索引访问
和字符串一样,列表也支持索引——从 0 开始编号:
list_demo = ['Java', 'C#', 'Python', 'PHP']print(list_demo[1]) # C#(正向索引)print(list_demo[-3]) # C#(反向索引,从 -1 开始)
正向索引: 0 1 2 3 Java C# Python PHP反向索引: -4 -3 -2 -1
切片访问
li_one = ['p', 'y', 't', 'h', 'o', 'n']print(li_one[1:4:2]) # 步长 2,取索引 1~3 → ['y', 'h']print(li_one[2:]) # 索引 2 至末尾 → ['t', 'h', 'o', 'n']print(li_one[:3]) # 索引 0~2 → ['p', 'y', 't']print(li_one[:]) # 全部 → ['p', 'y', 't', 'h', 'o', 'n']print(li_one[::-1]) # 反转 → ['n', 'o', 'h', 't', 'y', 'p']
遍历列表
最常用的方式是用 for 循环:
li_one = ['p', 'y', 't', 'h', 'o', 'n']for li in li_one:print(li, end=' ') # p y t h o n
三、添加列表元素
列表是"可变"的,所以可以随时往里加东西。有三种方式:
append() —— 在末尾追加
list_one = [1, 2, 3, 4]list_one.append(5) # 末尾加 5print(list_one) # [1, 2, 3, 4, 5]list_one.append(['论语', '诗经']) # 末尾加一个列表(作为单个元素)print(list_one) # [1, 2, 3, 4, 5, ['论语', '诗经']]
注意:append() 把参数当作一个元素添加,不会展开嵌套的列表。
extend() —— 合并另一个列表
list_str = ['a', 'b', 'c']list_num = [1, 2, 3]list_str.extend(list_num) # 把 list_num 的每个元素逐一加入print(list_str) # ['a', 'b', 'c', 1, 2, 3]print(list_num) # [1, 2, 3](原列表不变)
insert() —— 在指定位置插入
names = ['小明', '小红', '小兰']names.insert(2, '小白') # 在索引 2 的位置插入print(names) # ['小明', '小红', '小白', '小兰']names.insert(1, ('张三', '李四')) # 插入元组作为单个元素print(names) # ['小明', ('张三', '李四'), '小红', '小白', '小兰']names.insert(10, '王五') # 索引超出范围,相当于在末尾追加print(names)names.insert(-10, '王五') # 负索引超出范围,相当于在开头插入print(names)
三种添加方式对比
| | | |
|---|
append(x) | | [1].append([2,3]) | [1, [2, 3]] |
extend(x) | | [1].extend([2,3]) | [1, 2, 3] |
insert(i, x) | | [1,2].insert(1,3) | [1, 3, 2] |
💡 小提示:append() 和 extend() 的区别很微妙——前者把参数当"一个元素"添加,后者把参数当"一组元素"逐个添加。新手常在这里踩坑。
四、列表元素排序
sort() —— 原地排序
sort() 会直接修改原列表,不会创建新列表:
li_one = [6, 2, 5, 3]li_two = [7, 3, 5, 4]li_three = ['python', 'java', 'php']li_one.sort() # 升序(默认)li_two.sort(reverse=True) # 降序li_three.sort(key=len) # 按长度排序print(li_one) # [2, 3, 5, 6]print(li_two) # [7, 5, 4, 3]print(li_three) # ['php', 'java', 'python']
sorted() —— 返回新列表
sorted() 不修改原列表,而是返回一个新列表:
li_one = [4, 3, 2, 1]li_two = sorted(li_one) # 升序print(li_one) # [4, 3, 2, 1](原列表不变)print(li_two) # [1, 2, 3, 4](新列表)
reverse() —— 反转
li_one = ['a', 'b', 'c', 'd']li_one.reverse()print(li_one) # ['d', 'c', 'b', 'a']
sort() vs sorted()
💡 建议:除非明确需要原地修改,否则推荐用 sorted(),因为不修改原数据更安全。
五、删除列表元素
Python 提供了多种删除方式:
del 语句
names = ['小明', '小红', '小兰']del names[0] # 删除索引 0 的元素print(names) # ['小红', '小兰']# del 还能删除整个变量del names# print(names) # 报错!变量已不存在
remove() —— 按值删除
chars = ['h', 'e', 'l', 'l', 'e']chars.remove('e') # 删除第一个匹配到的 'e'print(chars) # ['h', 'l', 'l', 'e']
注意:remove() 只删除第一个匹配的元素,需要确保元素存在,否则会报错。
pop() —— 按索引删除并返回
numbers = [1, 2, 3, 4, 5]print(numbers.pop()) # 5(删除并返回最后一个)print(numbers.pop(1)) # 2(删除并返回索引 1 的元素)print(numbers) # [1, 3, 4]
clear() —— 清空
names = [1, 2, 3]names.clear() # 清空所有元素print(names) # []
四种删除方式对比
| | |
|---|
del | del 列表[索引] | |
remove(x) | 列表.remove(x) | |
pop(i) | 列表.pop(索引) | |
clear() | 列表.clear() | |
六、列表推导式——一行代码搞定循环
列表推导式是 Python 最优雅的特性之一。它让你用一行代码完成"遍历+操作+生成列表"的工作。
基本形式
# 普通写法ls = [1, 2, 3, 4, 5, 6, 7, 8]result = []for data in ls: result.append(data * data)print(result)# 列表推导式ls = [1, 2, 3, 4, 5, 6, 7, 8]result = [data * data for data in ls]print(result)
两种写法结果一样:[1, 4, 9, 16, 25, 36, 49, 64]
带条件过滤
ls = [1, 2, 3, 4, 5, 6, 7, 8]# 只取大于 4 的元素new_ls = [temp for temp in ls if temp > 4]print(new_ls) # [5, 6, 7, 8]
条件表达式(三目运算)
ls = [1, 2, 3, 4, 5, 6, 7, 8]# 偶数不变,奇数加 1new_ls = [temp if temp % 2 == 0else temp + 1for temp in ls]print(new_ls) # [2, 2, 4, 4, 6, 6, 8, 8]
双层循环
ls_one = [1, 2, 3]ls_two = [3, 4, 5]# 两两相加ls_three = [x + y for x in ls_one for y in ls_two]print(ls_three) # [4, 5, 6, 5, 6, 7, 6, 7, 8]
这相当于:
result = []for x in ls_one:for y in ls_two: result.append(x + y)
列表推导式语法总结
[表达式 for 变量 in 可迭代对象 if 条件]
💡 建议:列表推导式很强大,但不要过度使用。如果逻辑超过两层循环或条件太复杂,还是用普通 for 循环更清晰。
小结
列表是 Python 中最常用的数据类型,这一节的内容非常实用:
| | |
|---|
| [] | |
| lst[i] | |
| append()extend()insert() | |
| sort()sorted()reverse() | |
| delremove()pop()clear() | |
| [expr for x in iter if cond] | |
下一节我们来看列表的"亲戚"——元组。它跟列表几乎一样,但有重要的区别。