将项附加到列表列表中的指定列表(Python)
目前我正在通过解决ProjectEuler的问题来练习编程技能,现在我在Python上遇到了一些(我认为)奇怪的行为 当我这样做时:将项附加到列表列表中的指定列表(Python),python,list,append,Python,List,Append,目前我正在通过解决ProjectEuler的问题来练习编程技能,现在我在Python上遇到了一些(我认为)奇怪的行为 当我这样做时: list = [[1]]*20 我得到了一个包含元素1的20个列表,正如预期的那样。但是,当我想在这个列表的第三个元素中附加一个2时,我会按如下方式执行: list[3].append(2) 但是,这会更改列表中的所有元素。即使我绕道而行,比如: l = list[3] l.append(2) list[3] = l 我所有的元素都变了。谁能告诉我如何做到这
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
非常感谢您的快速回复。直到我发现了这个好奇,我才知道程序中的错误在哪里。很高兴知道这一点,谢谢。:)事实上,我注意到了前面编辑中提到的问题。这只是为了这个例子,我不会再这样做了。@SanderKersten别担心。我只是觉得它值得一提,因为它似乎经常出现。。。我曾经在自己的代码中犯过这样的错误,每次我在编辑器中使用一个小的三行函数,然后将它复制到一个更大的程序中,破坏一切,因此,我不得不养成一个习惯,就是从不使用变量的类型名。我最典型的缺点是列表中的列表
或任何中的s
类型的迭代器,这将保留循环运行的整个范围内的变量名。
c = list((1,2,3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not callable