我目前正在通过解决 euler 项目的问题来练习我的编程技能,现在我在 Python 上遇到了一些(在我看来)奇怪的行为。
当我这样做时:
list = [[1]]*20
如预期的那样,我得到了包含元素 1 的 20 个列表的列表。但是,当我想将 2 append 到该列表的第三个元素时,我会按如下方式进行:
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
只是将 reference 复制到从 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