列表
约 3285 字大约 11 分钟
2025-04-04
列表 的关键字是 list。在 Python 中,最常用的三种用来储存数据的数据结构分别是 字典、列表 和 字符串,可见它是十分重要的。
- 定义
- 列表元素的增加
- 列表元素的删除
- 列表元素的修改
- 1对同一个列表跑 append、extend、insert,把单元素、可迭代、位置插入这三件事分清。
- 2故意对一个列表 += 另一个列表,再用 = + 重新赋值,对比 id —— 体会 += 原地改、= + 换对象。
- 3试 lst.remove(x) 找不到时的 ValueError,养成“先 in 后 remove”的习惯。
- 4用 lst[::-1] 切出反转副本,再用 lst.reverse() 原地反转,理解两种反转的区别。
- 5对 [[0]*3]*3 这种二维列表的每一行追加元素,看到 3 行同步变化 —— 体会浅拷贝陷阱。
定义
列表 的关键字是 list。在 Python 中,最常用的三种用来储存数据的数据结构分别是 字典、列表 和 字符串,可见它是十分重要的。
列表的作用更像是一种容器,形象一点说就是我们用的书包:
- 列表能储存大量数据
- 列表能储存任意不同数据类型的数据
与列表相对照,我们先来观察一下这样一个字符串:a = '123aliceTrue' 这个字符串中包含数字、字母和布尔值,但是表现出来的全都是字符串。我们虽然能够通过索引取到内容,但取到的值仍然是字符串。这就需要我们进行额外的判断转换操作。列表则不同,列表可以储存不同类型的数据,并且可以随时把它们直接取出来用。就像把东西装到书包里,用的时候直接取出来即可。
我们可以通过如下方法定义一个列表:
lst = [1, 'alice', True]列表中的每个元素以逗号分隔。各个元素以原本的数据类型存储在列表中。
列表是可变数据类型,因此可以对列表本身进行修改。与字符串方法不同,列表方法一般没有返回值,而是直接对原列表进行修改。所以一般也不需要使用变量接收返回值。
列表元素的增加
列表元素的增加主要有三种方法:.append()、.insert() 和 .extend()。
.append() 方法实在列表的末尾添加内容。.append() 的参数就是需要增加的列表元素:
python playground
lst = ['Python学习手册', '核心编程']
print(lst.append('流畅的Python')) # None
print(lst) # ['Python学习手册', '核心编程', '流畅的Python'].append() 方法的返回值为 None。而当我们打印列表 lst 时发现,列表已经被改变。这里我们可以得出结论:
- 列表是可变数据类型
.append()操作会直接对列表进行修改而不需要重新赋值
.insert() 方法用来向列表中插入数据。.insert() 方法有两个参数,参数 1 是要插入位置的 索引值,参数 2 是要插入的 内容:
python playground
lst = ['Python学习手册', '核心编程']
lst.insert(1, '流畅的Python')
print(lst) # ['Python学习手册', '流畅的Python', '核心编程']实际操作中,不推荐使用 .insert() 方法。因为一旦使用这个方法,需要把插入位置后的每一个元素都后移一位,且发生索引值的变化,有可能给项目带来不可预测的影响。
.extend() 方法也是在列表的最后插入内容。.extend() 方法的参数必须是可迭代对象。执行 .extend() 方法时,会将参数内容 迭代追加 到列表结尾:
python playground
lst = ['Python学习手册', '核心编程']
lst.extend('流畅的Python')
print(lst) # ['Python学习手册', '核心编程', '流', '畅', '的', 'P', 'y', 't', 'h', 'o', 'n'].extend() 方法用来将多个数据 批量添加到列表末尾
两个列表的 + 操作同样可以实现列表的合并,但是需要注意区分列表的 += 和 =+ 操作的不同。old_list += new_list 等价于 old_list.extend(new_list),是在 old_list 基础上执行的合并操作。而 old_list = old_list + new_list 是新建立一个列表对象覆盖到 old_list 上。这两种操作的结果都是合并两个列表,但是如果有其他变量引用 old_list,那么结果就会有所差别:
python playground
old_list = [1, 2, 3]
old_list2 = old_list
new_list = [2, 3, 4]
old_list += new_list # 在 old_list 基础上扩充列表
print(old_list) # [1, 2, 3, 2, 3, 4]
print(old_list2) # [1, 2, 3, 2, 3, 4]
print(old_list is old_list2) # True
# 注释掉上面的代码后再执行下面的代码
old_list = old_list + new_list # 创建新列表
print(old_list) # [1, 2, 3, 2, 3, 4]
print(old_list2) # [1, 2, 3]
print(old_list is old_list2) # False列表元素的删除
列表元素的删除主要有四种方法:.remove()、.pop()、.clear() 和 del。
.remove() 方法可以删除指定元素名的列表元素,它的参数是要删除元素的元素名:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst.remove('王二麻子')
print(lst) # ['张三', '李四', '小桃红', '小明', '李华'].pop() 方法如果不加参数的话,默认删除列表中的最后一个元素,并且有返回值,返回的内容是是被删除的元素。.pop() 是唯一一个有返回值的列表元素删除方法:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
print(lst.pop()) # 李华
print(lst) # ['张三', '李四', '王二麻子', '小桃红', '小明'].pop() 方法也可以通过输入索引参数的方法,删除指定位置的列表元素:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
print(lst.pop(1)) # 李四
print(lst) # ['张三', '王二麻子', '小桃红', '小明', '李华'].clear() 方法用来将列表清空,最终会得到一个空列表:
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst.clear()
print(lst) # []del 是用来删除的关键字。del 后面直接跟列表名,会将列表整个删除掉:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
del lst
print(lst) # 报错 NameError: name 'lst' is not defined程序报错,因为 lst 已经被从内从中整个移除。后来 print 调用 lst 时,找不到相应的内容,所以报错。
也可以用 del 删除指定索引的列表元素:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
del lst[2]
print(lst) # ['张三', '李四', '小桃红', '小明', '李华']del也可以通过切片来批量删除多个列表元素:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
del lst[1:4]
print(lst) # ['张三', '小明', '李华']列表元素的修改
列表元素可以通过索引值赋值直接修改:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst[2] = '老王'
print(lst) # ['张三', '李四', '老王', '小桃红', '小明', '李华']也可以通过列表的切片方法对列表元素进行批量修改:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst[1:4] = 10, 20, 30
print(lst) # ['张三', 10, 20, 30, '小明', '李华']切片获取的内容空间是连续的时候,修改时内容可以多可以少;切片获取的内容空间是不连续的时候,修改时内容必须一一对应:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst[1:4] = 10, 20, 30, 40 # 切片空间连续,可多
print(lst) # ['张三', 10, 20, 30, 40, '小明', '李华']
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst[1:4] = 10, 20 # 切片空间连续,可少
print(lst) # ['张三', 10, 20, '小明', '李华']
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
lst[1:5:2] = ['alice', 'bob'] # 切片空间不连续,必须一一对应
print(lst) # ['张三', 'alice', '王二麻子', 'bob', '小明', '李华']列表元素的查看
列表元素可以通过索引查询和 for 循环遍历两种方法查看:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
print(lst[3])
for i in lst:
print(i)需要注意的是,进行切片操作时,获取的内容时切片的原数据本身。也就是说,切片不会改变数据类型。字符串切片后得到的还是字符串,列表切片后得到的还是列表:
python playground
lst = ['张三', '李四', '王二麻子', '小桃红', '小明', '李华']
print(lst[1:4]) # ['李四', '王二麻子', '小桃红']
a = 'alice'
print(a[1:3]) # li小结
- 列表是可变数据类型,可迭代数据类型,有序的数据结构
- 列表用来储存大量数据,并且可以储存不同数据类型
- 列表就是一个容器
- 列表储存的是元素的内存地址
列表的嵌套
因为列表可以储存各种数据类型的数据,那么列表当然也可以储存列表,这就造成了列表的嵌套。
现在有这样一个相互嵌套的列表:
lst = [1, 'alice', True, ['bob', '污', ['嫂子', '衣服多']], ['tom', '吹nb', '熬鸡汤', ['嫂子', '教育', '从基层做起']]]如果我们想调用其中的 '衣服多' 这个字符串,该怎么做呢?
我们可以像下面这样逐层操作:
lst1 = lst[3]
lst2 = lst1[2]
lst3 = lst2[1]这样,lst3 就是我们想要的 '衣服多' 字符串。
但是这样的操作实在太过繁琐。我们发现,lst1 = lst[3],既然如此,第二个式子我们可不可以把 lst1[2] 替换成 lst[3][2] 呢?那进一步说,我们可不可以直接通过 lst[3][2][1] 来调出 '衣服多' 字符串呢?
答案是完全可以的:
python playground
lst = [1, 'alice', True, ['bob', '污', ['嫂子', '衣服多']], ['tom', '吹nb', '熬鸡汤', ['嫂子', '教育', '从基层做起']]]
print(lst[3][2][1]) # 衣服多
print(lst[4][3][1]) # 教育像这样调用嵌套在内层列表元素的方法也被称作 降维,就是将类似于 ['bob', '污', ['嫂子', '衣服多']] 的结构当作一个元素查看
反转
对列表进行反转操作,我们可以通过切片的方式进行:
python playground
lst = [1, 2, 3, 4, 5, 6]
print(lst[::-1])这种方法并没有对原来的列表进行修改,而是创建了一个新列表。如果我们想对原来的列表进行改动,可以将切片后的结果赋值给 lst。也可以使用 .reverse() 的方法,对列表本身进行原地的反转操作:
python playground
lst = [1, 2, 3, 4, 5, 6]
lst.reverse()
print(lst) # [6, 5, 4, 3, 2, 1]排序
列表的 .sort() 方法可以将混乱的列表排序,默认是按照升序排序:
python playground
lst = [2, 1, 3, 4, 6, 5]
lst.sort()
print(lst) # [1, 2, 3, 4, 5, 6]我们可以混合使用 reverse 方法将升序的列表反转,达到降序的目的。也可以通过将 .sort() 方法中的参数 reverse 设置为 True,来让列表进行降序排序:
python playground
lst = [2, 1, 3, 4, 6, 5]
lst.sort(reverse=True)
print(lst) # [6, 5, 4, 3, 2, 1].index() 方法
.index() 方法通过元素名来查找该元素在列表中的索引:
::: python-repl editable
lst = [1, 2, 3, 4, 6, 5]
print(lst.index(4)) # 3:::
需要注意的是,如果需要查询的元素在列表中不止一个,.index() 方法只会返回从左面数第一个元素的索引值:
python playground
lst = [1,2,3,4,4,6,5]
print(lst.index(4)) # 3列表的加法和乘法
跟字符串类似,列表也可以进行加法和乘法的操作:
python playground
lst1 = [1, 2, 3, [4]]
lst2 = [4, 5, 6]
print(lst1 + lst2) # [1, 2, 3, [4], 4, 5, 6]
print(lst2 * 3) # [4, 5, 6, 4, 5, 6, 4, 5, 6]需要注意的是,列表的加法和乘法都是新开一个空间存储结果,而不是对原列表进行操作。但是加法和乘法的结果所使用的元素仍然是原列表中的。相应的操作与浅拷贝就很类似了:
python playground
lst1 = [1, 2, 3, [4]]
lst2 = [4, 5, 6]
l_sum = lst1 + lst2
l_sum[3].append(9)
print(lst1, lst2, l_sum) # [1, 2, 3, [4, 9]] [4, 5, 6] [1, 2, 3, [4, 9], 4, 5, 6]
l_multi = lst1 * 2
l_multi[3].append(8)
print(lst1, lst2, l_multi) # [1, 2, 3, [4, 9, 8]] [4, 5, 6] [1, 2, 3, [4, 9, 8], 1, 2, 3, [4, 9, 8]]- 列表是有序、可变、可迭代的“万能容器”,方法基本都是原地修改、返回 None。
- 增加:append 加单个、extend/+= 批量、insert 按位置(性能差,少用)。
- 删除:remove 按值、pop 按索引并返回、del 删切片或整体、clear 清空。
- 排序:sort() 原地排,sorted() 返回新列表;reverse=True 即降序。
- + 和 * 生成新列表,但元素仍是同一引用 —— 用 list * n 构造二维列表会踩浅拷贝坑。
版权所有
版权归属:Shuo Liu
