5

目前,我正在通过解决来自项目 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]]

提前致谢。

4

1 回答 1

12

Python 列表是可变对象,因此当您这样做时,[[1]]*20它会创建一个列表对象[1],然后将 20 个对它的引用放在顶级列表中。

就可变性问题而言,这与以下相同

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

发生这种情况是因为仅将列表实例的引用b=a从复制到。他们都指的是同一个实际列表。ab

为了创建列表列表,就像您在上面尝试的那样,您需要为每个条目创建一个唯一列表。列表推导效果很好:

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
于 2013-03-19T22:44:22.240 回答