Python 列表切片详解
庖丁解牛,「以无厚入有间」。Python 的列表切片大抵也是这个意思——用最薄的语法,在数据的骨节之间游刃。三个参数,两个冒号,不声不响地把一整条列表分割成你需要的任何形状。
列表切片(List Slicing)是 Python 中访问列表子序列的核心语法。通过切片可以高效地提取、复制或操作列表的任意部分,无需编写循环。语法简洁到近乎沉默,却是日常编程中最频繁的手势之一。
核心概念
基本语法
| 参数 | 说明 | 默认值 |
|---|
start | 起始索引(包含) | 0 |
stop | 结束索引(不包含) | 列表长度 |
step | 步长 | 1 |
三个参数都可以省略,省略即取默认值。这种设计哲学很 Python:你不说的,它替你想好了。
正向索引
从左到右,从 0 开始:
1
2
3
4
5
6
| fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
# 索引: 0 1 2 3 4
fruits[1:4] # ["香蕉", "橙子", "葡萄"]
fruits[:3] # ["苹果", "香蕉", "橙子"]
fruits[2:] # ["橙子", "葡萄", "西瓜"]
|
负索引
从右到左,从 -1 开始。像是站在列表末尾往回看——有时候回头看,反而更清楚要取哪些。
1
2
3
4
5
6
| fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
# 负索引: -5 -4 -3 -2 -1
fruits[-3:] # ["橙子", "葡萄", "西瓜"] 取最后3个
fruits[:-2] # ["苹果", "香蕉", "橙子"] 去掉最后2个
fruits[-3:-1] # ["橙子", "葡萄"] 从倒数第3到倒数第2
|
索引对照图
元素: ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
正索引: 0 1 2 3 4
负索引: -5 -4 -3 -2 -1
正负索引指向同一个元素,只是观察的方向不同。正索引是从起点出发数步数,负索引是从终点倒着量距离。两套坐标系,一张地图。
步长的使用
1
2
3
4
5
6
| nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
nums[::2] # [0, 2, 4, 6, 8] 每隔一个取一个
nums[1::2] # [1, 3, 5, 7, 9] 从索引1开始,每隔一个
nums[::-1] # [9, 8, 7, ..., 0] 反转列表
nums[7:2:-1] # [7, 6, 5, 4, 3] 逆向切片
|
实践应用
应用一:保留最近 N 条记录
在对话系统中,控制历史消息长度:
1
2
3
4
5
6
| messages = ["消息1", "消息2", "消息3", "消息4", "消息5"]
max_history = 3
# 只保留最近 3 条消息
history = messages[-max_history:]
# history = ["消息3", "消息4", "消息5"]
|
记忆有限,只留最近的。这一行切片做的事情,和人脑的遗忘曲线倒有几分相似。
应用二:复制列表
1
2
| original = [1, 2, 3]
copy = original[:] # 浅拷贝,创建新列表
|
应用三:反转列表
1
2
| text = "Hello"
reversed_text = text[::-1] # "olleH"
|
应用四:分页处理
1
2
3
4
5
6
| data = list(range(100))
page_size = 10
page = 3
# 获取第 3 页数据(索引 20-29)
page_data = data[(page-1)*page_size : page*page_size]
|
注意事项
切片不会越界
1
2
3
| nums = [1, 2, 3]
nums[10:20] # [] 不报错,返回空列表
nums[-100:] # [1, 2, 3] 等同于整个列表
|
索引取值越界会报 IndexError,但切片不会。它只是沉默地返回能给你的那部分,给不了的,就给一个空列表。这种宽容在别的语言里并不常见。
切片返回新列表
1
2
3
4
5
| original = [1, 2, 3]
sliced = original[1:]
sliced[0] = 99
print(original) # [1, 2, 3] 原列表不变
|
字符串也支持切片
1
2
3
| text = "Python"
text[0:2] # "Py"
text[-3:] # "hon"
|
要点总结
- 切片语法:
list[start:stop:step] - 负索引从 -1 开始,表示列表末尾
list[-n:] 取最后 n 个元素list[:-n] 去掉最后 n 个元素list[::-1] 反转列表- 切片不会越界报错,返回空列表或可用部分
- 切片返回新列表,不修改原列表
参考资料
两个冒号之间,藏着取舍的全部学问。写到这里忽然想起《老子》那句:「为学日益,为道日损。」切片的设计恰好反过来——语法越损(省略),能做的事越益(丰富)。大概好的工具都是这样:用最少的符号,表达最多的意图。