Python 列表 — 最常用的数据结构
学习列表的创建、索引、切片和常用方法 · 难度:入门 · +10XP
Python 列表 — 最强大的数据容器
一、什么是列表?为什么它是 Python 最常用的数据结构?
列表(List)是 Python 中最核心、最灵活的数据结构。它是一个有序、可变、可包含任意类型元素的容器。你可以把列表想象成一列有编号的储物柜:每个柜子有一个编号(索引),里面可以存放任何东西,而且你可以随时添加新的柜子、移除旧的柜子,或更换柜子里的物品。
为什么列表如此重要?
- 有序存储 — 元素保持插入顺序,支持索引访问
- 动态大小 — 无需预定义大小,自动扩容
- 混合类型 — 同一列表可以包含数字、字符串、甚至其他列表
- 丰富的内置方法 — Python 提供了强大的列表操作方法
- 可迭代 — 可以方便地用 for 循环遍历
- 在数据分析(pandas)、Web 开发(Django ORM)、日常脚本中,列表无处不在
二、列表 vs 元组 vs 集合 — 三大序列对比
| 特性 | 列表 list | 元组 tuple | 集合 set |
|---|---|---|---|
| 写法 | [1, 2, 3] | (1, 2, 3) | {1, 2, 3} |
| 可变性 | 可变(可增删改) | 不可变(创建后不可改) | 可变 |
| 有序性 | 有序 | 有序 | 无序(不保证顺序) |
| 重复元素 | 允许 | 允许 | 自动去重 |
| 索引访问 | 支持 | 支持 | 不支持 |
| 作为字典键 | 不可以 | 可以 | 不可以 |
| 内存占用 | 较大 | 较小 | 中等 |
| 典型场景 | 需频繁增删改的数据 | 固定的配置、坐标 | 去重、成员检查 |
三、列表方法速查表
| 方法 | 功能 | 返回值 | 是否修改原列表 |
|---|---|---|---|
| append(x) | 在末尾添加元素 | None | 是 |
| insert(i, x) | 在索引 i 处插入 | None | 是 |
| extend(iter) | 合并另一个可迭代对象 | None | 是 |
| remove(x) | 删除第一个值为 x 的元素 | None | 是 |
| pop(i=-1) | 删除并返回索引 i 的元素 | 被删除的元素 | 是 |
| clear() | 清空列表 | None | 是 |
| index(x) | 返回第一个值为 x 的索引 | 整数索引 | 否 |
| count(x) | 统计 x 出现的次数 | 整数 | 否 |
| sort(key=, reverse=) | 就地排序 | None | 是 |
| reverse() | 就地反转 | None | 是 |
| copy() | 浅拷贝 | 新列表 | 否 |
四、详细代码示例(逐行注释)
# ======== 1. 创建列表的多种方式 ========
# 直接创建
fruits = ["苹果", "香蕉", "橙子"] # 常用方式
mixed = [1, "hello", 3.14, True] # 混合类型列表
nested = [[1, 2], [3, 4]] # 嵌套列表(二维数组)
# 使用构造函数
numbers = list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
chars = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']
# 列表推导式(List Comprehension,Python 特色!)
squares = [x**2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
evens = [x for x in range(20) if x % 2 == 0] # 带条件的推导式:[0,2,4,...,18]
pairs = [(x, y) for x in "AB" for y in "12"] # 笛卡尔积:[('A','1'),('A','2'),...]
# ======== 2. 索引和切片 ========
nums = [10, 20, 30, 40, 50]
print(nums[0]) # 10 — 第一个元素(索引从 0 开始)
print(nums[-1]) # 50 — 最后一个元素(负数从末尾倒着数)
print(nums[1:4]) # [20, 30, 40] — 切片 [开始:结束](不包含结束索引)
print(nums[:3]) # [10, 20, 30] — 从开头到索引 2
print(nums[2:]) # [30, 40, 50] — 从索引 2 到末尾
print(nums[::2]) # [10, 30, 50] — 步长为 2(隔一个取一个)
print(nums[::-1]) # [50, 40, 30, 20, 10] — 步长为负 = 反转列表!
# ======== 3. 添加元素 ========
fruits = ["苹果", "香蕉"]
fruits.append("橙子") # 末尾添加 → ['苹果', '香蕉', '橙子']
fruits.insert(1, "葡萄") # 在索引 1 处插入 → ['苹果', '葡萄', '香蕉', '橙子']
fruits.extend(["西瓜", "草莓"]) # 合并另一个列表 → 添加多个元素
print(fruits) # ['苹果', '葡萄', '香蕉', '橙子', '西瓜', '草莓']
# ======== 4. 删除元素 ========
fruits.remove("香蕉") # 删除第一个匹配的值(找不到会报错!)
popped = fruits.pop() # 删除并返回最后一个元素 → '草莓'
popped2 = fruits.pop(0) # 删除并返回索引 0 的元素 → '苹果'
del fruits[1] # 用 del 语句删除指定索引
fruits.clear() # 清空所有元素 → []
# 安全删除:先检查
if "芒果" in fruits:
fruits.remove("芒果")
# ======== 5. 查找和统计 ========
nums = [1, 3, 5, 3, 7, 3, 9]
print(nums.index(3)) # 1 — 第一个 3 的索引
print(nums.index(3, 2)) # 3 — 从索引 2 开始找,找到索引 3 的 3
print(nums.count(3)) # 3 — 3 出现了 3 次
print(5 in nums) # True — 成员检查(推荐!)
print(10 not in nums) # True — 不在列表中
# ======== 6. 排序 ========
nums = [3, 1, 4, 1, 5, 9, 2]
nums.sort() # 就地升序排序 → [1, 1, 2, 3, 4, 5, 9]
nums.sort(reverse=True) # 就地降序排序 → [9, 5, 4, 3, 2, 1, 1]
# 自定义排序(按字符串长度)
words = ["apple", "pie", "a", "banana"]
words.sort(key=len) # 按长度排序 → ['a', 'pie', 'apple', 'banana']
words.sort(key=lambda w: w[-1]) # 按最后一个字母排序
# sorted() 返回新列表(不改变原列表)
original = [3, 1, 2]
new_list = sorted(original) # original 不变!new_list = [1, 2, 3]
# ======== 7. 列表推导式高级用法 ========
# 带条件的推导
scores = [85, 92, 78, 95, 88]
passed = [s for s in scores if s >= 90] # [92, 95]
# 映射转换
names = ["alice", "bob", "charlie"]
upper_names = [n.upper() for n in names] # ['ALICE', 'BOB', 'CHARLIE']
# 嵌套推导(展平二维列表)
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [x for row in matrix for x in row] # [1, 2, 3, 4, 5, 6]
# ======== 8. 常用内置函数配合列表 ========
nums = [3, 1, 4, 1, 5]
print(len(nums)) # 5 — 长度
print(sum(nums)) # 14 — 总和
print(max(nums)) # 5 — 最大值
print(min(nums)) # 1 — 最小值
print(list(enumerate(nums))) # [(0,3),(1,1),(2,4),(3,1),(4,5)] — 带索引
# zip 组合多个列表
names = ["小明", "小红", "小刚"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}:{score}分") # 同时遍历两个列表
# ======== 9. 列表复制陷阱(重要!) ========
a = [1, 2, [3, 4]]
b = a # 不是复制!b 和 a 指向同一个对象
c = a.copy() # 浅拷贝:顶层复制,但嵌套列表仍是共享的
import copy
d = copy.deepcopy(a) # 深拷贝:完全独立
a[2][0] = 999
print(b) # [1, 2, [999, 4]] — b 受影响(同一对象)
print(c) # [1, 2, [999, 4]] — c 受影响(浅拷贝!)
print(d) # [1, 2, [3, 4]] — d 不受影响(深拷贝!)
五、实践任务
- 创建一个空列表,用
append添加 5 个数字,然后用sort排序并输出 - 使用列表推导式生成 1 到 100 中所有能被 3 整除但不能被 5 整除的数
- 编写函数
remove_duplicates(lst),接收一个列表,返回去重后的新列表(保持原顺序) - 有一个学生成绩列表
[("小明", 85), ("小红", 92), ("小刚", 78)],按分数降序排序并输出 - 创建一个 3x3 的二维列表(矩阵),计算对角线元素之和