Python 中列表完全指南
本文档面向零基础新手,详细讲解 列表(list) 是什么、为什么索引从 0 开始、负索引(-1 表示最后一个)、以及如何修改、添加和删除元素,并配有大量示例。
第一部分:列表是什么?
一、列表的概念
列表 是 Python 里的一种数据结构,用来按顺序存放多个值。可以把它想象成一排带编号的格子:每个格子里放一个元素,从左到右依次是第 0 个、第 1 个、第 2 个……
特点:
- 有序:元素有固定顺序,通过“位置”(索引)访问
- 可重复:同一个值可以出现多次
- 可修改:可以改、增、删元素
- 可混合类型:一个列表里可以同时放数字、字符串、布尔值等(一般不推荐混太多类型,以免难维护)
基本写法: 用方括号 [] 把多个元素括起来,元素之间用逗号 , 分隔。
# 空列表
empty = []
print(empty) # []
# 只有数字
ages = [18, 20, 22]
print(ages) # [18, 20, 22]
# 只有字符串
names = ["小明", "小红", "小刚"]
print(names) # ['小明', '小红', '小刚']
# 混合类型(可以,但不建议混太多)
mixed = [1, "hello", 3.14, True]
print(mixed) # [1, 'hello', 3.14, True]
二、用 list() 创建列表
除了用 [] 写死,还可以用 list() 把“可迭代”的东西转成列表(如字符串、range)。
# 字符串转列表:每个字符一个元素
lst = list("abc")
print(lst) # ['a', 'b', 'c']
# range 转列表
lst = list(range(5))
print(lst) # [0, 1, 2, 3, 4]
三、访问列表元素(用索引)
要取出列表里某一个元素,用 列表名[索引]。
索引 就是“第几个”的编号。在 Python 里,第一个元素的索引是 0,第二个是 1,依次类推。
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
# 0 1 2 3
print(fruits[0]) # 苹果(第 1 个)
print(fruits[1]) # 香蕉(第 2 个)
print(fruits[2]) # 橙子(第 3 个)
print(fruits[3]) # 葡萄(第 4 个)
索引超出范围会报错:
# print(fruits[4]) # 报错:只有 4 个元素,索引最大是 3
第二部分:为什么索引从 0 而不是 1 开始?
四、原因简述
在很多编程语言(包括 Python)里,列表、字符串的索引都从 0 开始,原因主要有:
-
和内存地址有关
在计算机里,列表在内存中是连续存放的。第 1 个元素的地址是“起始地址 + 0”,第 2 个是“起始地址 + 1”个单元……所以用 0 表示“偏移 0”,用 1 表示“偏移 1”,写公式和实现编译器更自然。 -
历史习惯
早期 C 等语言这样设计,很多后来的语言(包括 Python)沿用了“从 0 开始”的约定,这样大家写法统一,也方便和 C 等交互。 -
半开区间更统一
切片、循环里常用“从 0 到 n”的区间。从 0 开始时,范围 [0, n) 正好是 n 个元素,不会多一个或少一个,写起来不容易出错。
你只需要记住:在 Python 里,第一个元素是 0,第二个是 1,以此类推。 这是规定,习惯就好。
lst = ["A", "B", "C"]
# 0 1 2 ← 索引
print(lst[0]) # A(第 1 个)
print(lst[1]) # B(第 2 个)
第三部分:负索引与“最后一个元素”
五、索引可以是负数:从右边数
除了用 0、1、2… 从左边数,还可以用 -1、-2、-3… 从右边数:
- -1 表示最后一个元素
- -2 表示倒数第二个
- -3 表示倒数第三个,以此类推
索引指定为 -1,就可以让 Python 返回最后一个列表元素。
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
# 0 1 2 3
# -4 -3 -2 -1
print(fruits[-1]) # 葡萄(最后一个)
print(fruits[-2]) # 橙子(倒数第二个)
print(fruits[-3]) # 香蕉(倒数第三个)
print(fruits[-4]) # 苹果(倒数第四个,也就是第一个)
常见用法:取最后一个、倒数几个
scores = [80, 90, 85, 88]
print(scores[-1]) # 88(最后一次成绩)
print(scores[-2]) # 85(倒数第二次)
负索引同样不能越界(例如只有 4 个元素时,不能用 -5)。
第四部分:切片(取一段)
切片 用来取列表的一段,格式是 列表[开始:结束](包含开始,不包含结束)。不写开始表示从开头,不写结束表示到末尾。
nums = [10, 20, 30, 40, 50]
print(nums[1:4]) # [20, 30, 40](索引 1 到 3)
print(nums[:3]) # [10, 20, 30](前 3 个)
print(nums[2:]) # [30, 40, 50](从索引 2 到末尾)
print(nums[-2:]) # [40, 50](最后 2 个)
第五部分:修改、添加和删除元素
六、修改元素
列表是可变的:可以通过赋值直接改掉某个位置的值。
语法: 列表[索引] = 新值
fruits = ["苹果", "香蕉", "橙子"]
fruits[1] = "草莓" # 把索引 1 的元素改成 "草莓"
print(fruits) # ['苹果', '草莓', '橙子']
# 可以连续改多个
fruits[0] = "红苹果"
fruits[2] = "甜橙"
print(fruits) # ['红苹果', '草莓', '甜橙']
注意: 索引必须在有效范围内,否则会报错。
七、添加元素
7.1 append() —— 在末尾追加一个元素
用法: 列表.append(元素)
作用: 在列表最后加一个元素(可以是任意类型)。不产生新列表,直接改原列表。
nums = [1, 2, 3]
nums.append(4)
print(nums) # [1, 2, 3, 4]
nums.append(5)
print(nums) # [1, 2, 3, 4, 5]
注意: append 每次只加一个元素。若传入一个列表,会把整个列表当作一个元素加进去,而不是把列表里的元素逐个加上去。
nums = [1, 2, 3]
nums.append([4, 5]) # 把 [4, 5] 当作“一个元素”追加
print(nums) # [1, 2, 3, [4, 5]]
print(len(nums)) # 4(多了一个元素,这个元素是列表)
示例:用循环往列表里收集数据
scores = []
scores.append(80)
scores.append(90)
scores.append(85)
print(scores) # [80, 90, 85]
7.2 insert() —— 在指定位置插入一个元素
用法: 列表.insert(索引, 元素)
作用: 在指定索引位置插入一个元素,该位置及后面的元素整体往后移一位。直接修改原列表,不产生新列表。
索引规则:
insert(0, 元素):在最前面插入insert(len(列表), 元素):在最后面插入(效果和 append 一样)- 若索引大于列表长度,多数实现会插到末尾
lst = ["A", "B", "C"]
lst.insert(1, "X") # 在索引 1 处插入 "X"
print(lst) # ['A', 'X', 'B', 'C']
# 在开头插入
lst.insert(0, "头")
print(lst) # ['头', 'A', 'X', 'B', 'C']
# 在末尾插入(等价于 append)
lst.insert(len(lst), "尾")
print(lst) # ['头', 'A', 'X', 'B', 'C', '尾']
lst.insert(311, "Q") # 等价于 append
print(lst) # ['头', 'A', 'X', 'B', 'C', '尾', 'Q']
7.3 extend() —— 把另一个列表“接在后面”
用法: 列表.extend(另一个列表)
作用: 把另一个列表里的每个元素依次加到当前列表末尾(不是把“整个列表”当一个元素加进去)。
a = [1, 2]
b = [3, 4]
a.extend(b)
print(a) # [1, 2, 3, 4]
print(b) # [3, 4](b 不变)
和 append 的区别:
a = [1, 2]
a.append([3, 4]) # 把 [3, 4] 当作“一个元素”追加
print(a) # [1, 2, [3, 4]]
a = [1, 2]
a.extend([3, 4]) # 把 3、4 两个元素依次追加
print(a) # [1, 2, 3, 4]
7.4 用 + 拼接成新列表
用法: 列表1 + 列表2
作用: 得到新列表,不修改原来的两个列表。
a = [1, 2]
b = [3, 4]
c = a + b
print(c) # [1, 2, 3, 4]
print(a) # [1, 2](a 没变)
print(b) # [3, 4](b 没变)
八、删除元素
8.1 del 语句 —— 按索引删除
用法: del 列表[索引] 或 del 列表[切片]
作用: 删掉指定位置的一个元素(或切片范围内的一段),后面的元素会前移。
lst = ["A", "B", "C", "D"]
del lst[1] # 删除索引 1 的元素 "B"
print(lst) # ['A', 'C', 'D']
# 删除切片(一段)
lst = ["A", "B", "C", "D"]
del lst[1:3] # 删除索引 1 和 2
print(lst) # ['A', 'D']
8.2 remove() —— 按值删除(只删第一个)
用法: 列表.remove(值)
作用: 删掉列表中第一个等于该值的元素。若没有这个值会报错。
lst = ["苹果", "香蕉", "橙子", "香蕉"]
lst.remove("香蕉") # 只删第一个 "香蕉"
print(lst) # ['苹果', '橙子', '香蕉']
若要删的值不存在会报错:
# lst.remove("西瓜") # ValueError(列表里没有 "西瓜")
8.3 pop() —— 按索引删除并返回该元素
用法: 列表.pop() 或 列表.pop(索引)
作用:
pop():删掉最后一个元素,并返回它pop(索引):删掉指定索引的元素,并返回它
lst = ["A", "B", "C"]
last = lst.pop() # 删除并返回最后一个
print(last) # C
print(lst) # ['A', 'B']
lst = ["A", "B", "C"]
first = lst.pop(0) # 删除并返回索引 0 的元素
print(first) # A
print(lst) # ['B', 'C']
8.4 clear() —— 清空列表
用法: 列表.clear()
作用: 删掉列表里所有元素,列表变成空列表 []。
lst = [1, 2, 3]
lst.clear()
print(lst) # []
使用 del 语句还是 pop() 方法?
| 需求 | 更合适 | 说明 |
|---|---|---|
| 只删掉某个位置上的元素,不需要这个值 | del | 写法简单:del 列表[索引] |
| 删掉某个位置的元素,还要用到被删的值 | pop(索引) | x = 列表.pop(索引),后面可以用 x |
| 删掉最后一个并要用到它(如“出栈”) | pop() | last = 列表.pop() |
示例对比:
# 只删,不用值 → 用 del
lst = [1, 2, 3]
del lst[1]
print(lst) # [1, 3]
# 删的同时要拿到值 → 用 pop
lst = [1, 2, 3]
value = lst.pop(1)
print(value) # 2
print(lst) # [1, 3]
pop() 和 remove() 的区别
| 项目 | pop() | remove() |
|---|---|---|
| 按什么删 | 按索引(位置) | 按值(内容) |
| 写法 | 列表.pop() 或 列表.pop(索引) |
列表.remove(值) |
| 返回值 | 返回被删的元素 | 不返回(None) |
| 是否要知道位置 | 需要知道索引(或删最后一个用 pop()) | 不需要,只要知道要删的值 |
| 同一值出现多次 | 一次只删一个位置 | 只删第一个匹配的 |
示例对比:
# 按位置删,并拿到被删的值 → pop
lst = [10, 20, 30]
x = lst.pop(1)
print(x, lst) # 20 [10, 30]
# 按值删,不关心位置,也不需要拿到值 → remove
lst = [10, 20, 30]
lst.remove(20)
print(lst) # [10, 30]
九、修改、添加、删除小结表
| 操作 | 写法示例 | 说明 |
|---|---|---|
| 修改 | lst[i] = 新值 |
把索引 i 的元素改成新值 |
| 末尾追加 | lst.append(元素) |
在末尾加一个元素 |
| 指定位置插入 | lst.insert(索引, 元素) |
在索引处插入,后面后移 |
| 接上另一列表 | lst.extend(另一列表) |
把另一列表的元素逐个加在末尾 |
| 按索引删 | del lst[i] 或 lst.pop(i) |
del 只删;pop 删并返回值 |
| 按值删 | lst.remove(值) |
删第一个等于该值的元素 |
| 删最后一个 | lst.pop() |
删最后一个并返回 |
| 清空 | lst.clear() |
删除所有元素 |
第六部分:其他常用操作
十、长度、是否包含、计数、查找索引
lst = [10, 20, 30, 20, 40]
print(len(lst)) # 5(元素个数)
print(20 in lst) # True(是否包含 20)
print(99 in lst) # False
print(lst.count(20)) # 2(20 出现几次)
print(lst.index(30)) # 2(第一个 30 的索引)
# lst.index(99) # 报错:99 不在列表中
十一、复制列表(避免“改一个两个都变”)
a = [1, 2, 3]
b = a # b 和 a 指向同一列表!
b.append(4)
print(a) # [1, 2, 3, 4](a 也被改了)
# 正确:复制一份
a = [1, 2, 3]
b = a.copy() # 或 b = a[:]
b.append(4)
print(a) # [1, 2, 3]
print(b) # [1, 2, 3, 4]
第七部分:排序
十二、sort() —— 对列表进行永久性排序
用法: 列表.sort() 或 列表.sort(reverse=True)
作用: 把列表在原地按顺序重新排列。直接修改原列表,不产生新列表,不返回值(返回 None)。
默认是升序(从小到大);加 reverse=True 为降序(从大到小)。
names = ["丁丁", "安安", "丙丙", "乙乙"]
names.sort()
print(names) # ['乙乙', '丙丙', '丁丁', '安安'](按字符/编码排序)
数字排序:
nums = [3, 1, 4, 1, 5]
nums.sort()
print(nums) # [1, 1, 3, 4, 5]
降序:names.sort(reverse=True)
nums = [3, 1, 4, 1, 5]
nums.sort(reverse=True)
print(nums) # [5, 4, 3, 1, 1]
names = ["丁丁", "安安", "丙丙"]
names.sort(reverse=True)
print(names) # ['丁丁', '丙丙', '安安']
重要: 叫“永久性”是因为原列表被改掉了,排序后原来的顺序就没了。若想保留原列表不变,用下面的 sorted()。
十三、sorted() —— 对列表进行临时排序
用法: sorted(列表) 或 sorted(列表, reverse=True)
作用: 根据原列表生成一个新的已排序列表,不修改原列表。默认升序,加 reverse=True 为降序。
names = ["丁丁", "安安", "丙丙"]
l = sorted(names) # 得到新列表,存在 l 里
print(l) # ['丙丙', '丁丁', '安安']
print(names) # ['丁丁', '安安', '丙丙'](原列表没变)
对比 sort 和 sorted:
# sort:改原列表
a = [3, 1, 2]
a.sort()
print(a) # [1, 2, 3]
# sorted:不改原列表,得到新列表
b = [3, 1, 2]
c = sorted(b)
print(b) # [3, 1, 2](b 不变)
print(c) # [1, 2, 3](c 是新的排序结果)
何时用哪个:
- 需要保留原列表,只要一个“排序后的副本” → 用 sorted(),例如
l = sorted(names) - 确定要直接改原列表,以后都用排序后的顺序 → 用 sort()
反转顺序
十四、reverse() —— 反转列表元素的排列顺序
用法: 列表.reverse()
作用: 把列表从头到尾反转。直接修改原列表,不产生新列表,不返回值(返回 None)。
lst = [1, 2, 3, 4]
lst.reverse()
print(lst) # [4, 3, 2, 1]
和“按值降序”不同: reverse 只反转顺序,不比较大小;sort(reverse=True) 是按大小降序排列。
nums = [1, 3, 2]
nums.reverse()
print(nums) # [2, 3, 1](只是倒过来)
nums = [1, 3, 2]
nums.sort(reverse=True)
print(nums) # [3, 2, 1](按数值从大到小)
若不想改原列表,只要“反转后的新列表”: 可以用切片 列表[::-1]。
lst = [1, 2, 3]
new_lst = lst[::-1]
print(new_lst) # [3, 2, 1]
print(lst) # [1, 2, 3](原列表不变)
列表长度
十五、len() —— 快速获悉列表的长度
用法: len(列表)
作用: 返回列表中元素的个数(一个整数)。不修改列表。
lst = [10, 20, 30]
print(len(lst)) # 3
names = ["小明", "小红"]
print(len(names)) # 2
empty = []
print(len(empty)) # 0
常见用途: 判断是否为空、循环次数、取最后一个元素的索引等。
lst = [1, 2, 3]
if len(lst) > 0:
print("最后一个元素索引是", len(lst) - 1)
print("最后一个元素是", lst[len(lst) - 1]) # 或 lst[-1]
第八部分:综合示例
十六、示例:成绩列表的增删改查
scores = [80, 90, 85]
print("原始:", scores)
print("最后一个:", scores[-1])
scores[1] = 92 # 修改第二门成绩
print("修改后:", scores)
scores.append(88) # 追加一门
print("追加后:", scores)
scores.remove(80) # 删掉 80
print("删除 80 后:", scores)
last = scores.pop() # 删掉最后一个并取出
print("弹出的最后一项:", last)
print("最终:", scores)
原始: [80, 90, 85]
最后一个: 85
修改后: [80, 92, 85]
追加后: [80, 92, 85, 88]
删除 80 后: [92, 85, 88]
弹出的最后一项: 88
最终: [92, 85]
十七、示例:用负索引取“最后几个”
nums = [10, 20, 30, 40, 50]
print(nums[-1]) # 50(最后一个)
print(nums[-2:]) # [40, 50](最后两个)
print(nums[-3:]) # [30, 40, 50](最后三个)
第八部分:小结表
| 主题 | 要点 |
|---|---|
| 列表是什么 | 有序、可重复、可修改的序列,用 [] 表示,元素用逗号分隔 |
| 索引从 0 开始 | 第一个元素是 0,第二个是 1;和历史、内存、区间写法有关 |
| 负索引 -1 | 列表[-1] 是最后一个,-2 是倒数第二个 |
| 修改 | 列表[索引] = 新值 |
| 添加 | append(元素) 末尾加;insert(索引, 元素) 指定位置插;extend(列表) 接在后面 |
| 删除 | del 列表[i] 按索引删;remove(值) 按值删第一个;pop() / pop(i) 删并返回;clear() 清空 |