在列表的列表中向指定列表添加项目(Python)
我现在正在通过解决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