在列表的列表中向指定列表添加项目(Python)

5 投票
1 回答
15491 浏览
提问于 2025-04-17 19:41

我现在正在通过解决Project Euler上的问题来练习我的编程技能,最近遇到了一些(我认为)奇怪的Python行为。

当我执行以下代码时:

list = [[1]]*20

我得到了一个包含20个列表的列表,每个列表里都有元素1,这个结果是我预期的。然而,当我想要在这个列表的第三个元素中添加一个2时,我是这样做的:

list[3].append(2)

但是,这样做却改变了列表中所有的元素。即使我绕个弯,比如:

l = list[3]
l.append(2)
list[3] = l

我的所有元素还是都被改变了。有没有人能告诉我该怎么做,才能得到像这样输出的结果:

[[1], [1], [1], [1, 2], [1] .... [1]]

提前谢谢大家。

1 个回答

12

Python中的列表是可变的对象,所以当你写 [[1]]*20 时,它实际上只创建了一个列表对象 [1],然后在最外层的列表中放了20个对这个列表的引用。

关于可变性的问题,这和下面的情况是一样的:

a = [1,2,3]
b = a
b.append(4)
a # [1,2,3,4]

这是因为 b=a 只是把列表实例的引用a 复制到了 b。它们实际上指向的是同一个列表。

如果你想创建一个包含多个列表的列表,就像你上面尝试的那样,你需要为每个条目创建一个独特的列表。使用列表推导式就很合适:

mainlist = [[1] for x in range(20)]
mainlist[0].append(2)
mainlist # [[1,2],[1],[1],...]

补充说明

另外,由于在Python中类型名称是元类,所以用类型名称来命名变量是个坏主意。这样做可能会在代码的后面引发一些问题:

a = range(3) # [0,1,2]
type(a) # (type 'list')
isinstance(a, list) # True

现在,创建一个名为 list 的变量。

list = range(3)
list # [0,1,2]
isinstance(list, list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

更不用说,这样你就不能使用 list() 这个操作符了。

c = list((1,2,3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable

撰写回答