操作员分配的列表列表不能引用特定的列表元素

时间:2019-08-27 17:32:21

标签: python

我正在建立一个以相同线条开头的二维矩阵。当我使用lines = n * [list(string)]创建列表列表以创建n个相同字符列表的列表时,它似乎可以工作。但是,当我尝试为行中的元素分配特定值时,该值会在所有行中复制。

我在Jupyter Notebook中执行了以下操作。显示代码和输出。我还尝试在矩阵中打印出特定元素的id(),以弄清楚到底发生了什么。如果我用乘法设置矩阵,则所有行似乎都在同一地址。对元素进行赋值会更改所有行。当我对列表进行硬编码时,元素以相同的地址开头,但是当我进行分配时,地址会更改。

Python真的应该像这样工作吗?

这是行不通的...

lines=11*[list('   |   |   ')] # Initialize matrix a list of lists
lines[0][0]='0'

for i in lines: print(i)
print('address of 0,0: '+str(id(lines[0][0])))
print('address of 1,0: '+str(id(lines[1][0])))
print('address of 2,0: '+str(id(lines[2][0])))

输出...

['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043952387048
address of 2,0: 2043952387048

这是起作用的...

lines=[[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '], # Initialize matrix with data.
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' '],
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']]

lines[0][0]='0'

for i in lines: print(i)
print('address of 0,0: '+str(id(lines[0][0])))
print('address of 1,0: '+str(id(lines[1][0])))
print('address of 2,0: '+str(id(lines[2][0])))

输出...

['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043951596632
address of 2,0: 2043951596632

2 个答案:

答案 0 :(得分:3)

这样做的时候

accessing value of ‘"STACKOVERFLOW"’ through a ‘const unsigned char’ glvalue in a constant expression

您只拨打一次lines=11*[list(' | | ')] 。它列出了一个列表,并且该列表被引用了11次。等效于:

list('   |   |   ')

只有一个temp = list(' | | ') lines = 11*[temp] 列表,这将创建一个列表,其中包含对该列表的11个引用。将列表相乘只会复制容器的外部结构,不会复制它所引用的对象。

使用:

temp

因此它将调用lines = [list(' | | ') for _ in range(11)] 11次,每次都会创建一个新列表。

答案 1 :(得分:0)

这个问题确实困扰着我,我终于在文档中找到了答案。文档甚至说:“这常常困扰着新Python程序员; ...”它的工作方式在此处写成https://docs.python.org/3.6/library/stdtypes.html#typesseq-common

此“功能”在注释2中有完整描述,该表与“ s * n或n * s”表条目一起提供。

但是,我认为文档中关于“ s + t”表条目的遗漏。注释6和7对此适用。也许需要添加类似于2的注释?原因是因为运行以下代码时,您会得到相同的行为。

s=[[1,2,3]]
s = s + s
s[0][0]=4
print(s)

输出为“ [[4,2,3],[4,2,3]]”。

这个人并没有困扰我太多,因为我一直在期待它。