San*_*ten 5 python list append
我正在通过解决项目euler目前的问题来练习我的编程技巧,现在我遇到了一些(在我看来)Python上的奇怪行为.
当我做:
list = [[1]]*20
Run Code Online (Sandbox Code Playgroud)
我按预期获得了包含元素1的20个列表的列表.但是,当我想在此列表中向第三个元素添加2时,我会按如下方式执行此操作:
list[3].append(2)
Run Code Online (Sandbox Code Playgroud)
但是,这会更改列表中的所有元素.即使我绕道而行,例如:
l = list[3]
l.append(2)
list[3] = l
Run Code Online (Sandbox Code Playgroud)
我的所有元素都改变了.任何人都可以请告诉我如何做到这一点并获得如此输出:
[[1], [1], [1], [1, 2], [1] .... [1]]
Run Code Online (Sandbox Code Playgroud)
提前致谢.
Nis*_*n.H 11
Python列表是可变对象,因此当您这样做时,[[1]]*20它会创建一个列表对象[1],然后在顶层列表中放置20个引用.
就可变性问题而言,这与以下相同
a = [1,2,3]
b = a
b.append(4)
a # [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为b=a仅将列表实例的引用复制a到b.它们都指的是相同的实际列表.
为了创建列表列表,就像您在上面尝试过的那样,您需要为每个条目创建一个唯一的列表.列表理解效果很好:
mainlist = [[1] for x in range(20)]
mainlist[0].append(2)
mainlist # [[1,2],[1],[1],...]
Run Code Online (Sandbox Code Playgroud)
编辑
顺便说一句,由于类型名称是Python中的元类,因此通过类型名称命名变量是一个坏主意.原因是代码中可能会导致以下几个问题:
a = range(3) # [0,1,2]
type(a) # (type 'list')
isinstance(a, list) # True
Run Code Online (Sandbox Code Playgroud)
现在,创建一个名为的变量 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
Run Code Online (Sandbox Code Playgroud)
更何况,现在您无法使用list()运营商
c = list((1,2,3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable
Run Code Online (Sandbox Code Playgroud)