我正在建立一个以相同线条开头的二维矩阵。当我使用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
答案 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]]”。
这个人并没有困扰我太多,因为我一直在期待它。