我正在通过解决project euler中的问题来练习我的编程技能,现在我在Python上遇到了一些(在我看来)奇怪的行为。
当我这样做的时候:
list = [[1]]*20
我得到一个包含元素1的20个列表的列表,如预期的那样。但是,当我想向列表中的第三个元素添加2时,我会这样做:
list[3].append(2)
但是这会改变列表中的所有元素。即使我绕道而行,比如:
l = list[3]
l.append(2)
list[3] = l
我所有的元素都被改变了。谁能告诉我如何做到这一点,并得到这样的输出:
[[1], [1], [1], [1, 2], [1] .... [1]]
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