Python 操作员指定的列表列表可以';t引用特定列表元素

Python 操作员指定的列表列表可以';t引用特定列表元素,python,Python,我正在建立一个二维矩阵,它以相同的线开始。当我使用lines=n*[list(string)]创建一个列表列表来创建n个相同字符列表时,它似乎可以工作。但是,当我尝试为行中的元素指定特定值时,它会复制到所有行中 我在Jupyter笔记本中做了以下操作。显示代码和输出。我还打印了矩阵中特定元素的id(),同时试图弄清楚发生了什么。如果我用乘法设置矩阵,所有行似乎都在同一个地址。对元素赋值会更改所有行。当我硬编码列表时,元素以相同的地址开始,但当我赋值时,地址会改变 Python真的应该这样工作吗

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

我在Jupyter笔记本中做了以下操作。显示代码和输出。我还打印了矩阵中特定元素的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
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043951596632
address of 2,0: 2043951596632
以下是有效的方法

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', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
['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
['0', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
[' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ']
address of 0,0: 2043952387048
address of 1,0: 2043951596632
address of 2,0: 2043951596632
当你这样做的时候

lines=11*[list('   |   |   ')]
您只需调用
list(“| |”)
一次。它制作了一个列表,同一个列表被引用了11次。这相当于:

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

使用:


因此,它将调用
list()
11次,每次都创建一个新列表。

这个问题确实困扰着我,我终于在文档中找到了答案。文档甚至说,“这经常困扰新的Python程序员;……”它的工作原理写在这里

该“特性”在与“s*n或n*s”表项一起的注释2中有详细描述

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

s=[[1,2,3]]
s = s + s
s[0][0]=4
print(s)
输出为“[[4,2,3],[4,2,3]]”


这件事并没有让我太困扰,因为我早就料到了。

太多了[在你的回答中,但这个概念非常有效!我很抱歉在此详述,我希望了解编译器正在做什么。它真的应该这样工作吗?文档中哪里有可以解释这一点的东西?似乎编译器让我创建一个列表列表,但它像一个列表。这些操作的实用程序是什么?最简单的例子是:l=[0,1,2,3,4,5];l2=[l]+[l];l2[0][0]=9;print(l2);看起来确实像一个可变列表,bit不是。对此没有任何警告。我已经更新了答案,以更清楚地说明这是如何工作的。这里有更多关于这方面的信息。。。