首页 > 解决方案 > 运算符分配的列表列表不能引用特定的列表元素

问题描述

我正在设置一个以相同行开头的二维矩阵。当我使用 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

标签: python

解决方案


当你这样做

lines=11*[list('   |   |   ')]

你只打电话list(' | | ')一次。它列出了一个列表,并且同一个列表被引用了 11 次。它相当于:

temp = list('   |   |   ')
lines = 11*[temp]

只有一个temp列表,这将创建一个包含 11 个对该列表的引用的列表。乘以一个列表只会复制容器的外部结构,它不会复制它所引用的对象。

利用:

lines = [list('   |   |   ') for _ in range(11)]

所以它会调用list()11 次,每次都会创建一个新列表。


推荐阅读