Python 列表理解形成的矩阵和列表元素相乘形成的矩阵之间的区别?

Python 列表理解形成的矩阵和列表元素相乘形成的矩阵之间的区别?,python,math,matrix,Python,Math,Matrix,我试图将空矩阵的对角元素更改为1。 因此,当我使用相乘列表元素[[0]*4]*4形成一个矩阵,并将其对角线元素更改为1,它将所有元素更改为1。 但是,当我使用列表理解形成矩阵并将其对角线元素更改为1时,它工作正常。下面是上面提到的实现: mat1 = [ [ 0 for i in range(4) ] for j in range( 4 ) ] # Using List Comprehensions mat2 = [ [ 0 ] * 4 ] * 4

我试图将空矩阵的对角元素更改为
1
。 因此,当我使用相乘列表元素
[[0]*4]*4
形成一个矩阵,并将其对角线元素更改为
1
,它将所有元素更改为
1
。 但是,当我使用列表理解形成矩阵并将其对角线元素更改为
1
时,它工作正常。下面是上面提到的实现:


mat1 = [ [ 0 for i in range(4) ]  for j in range( 4 ) ]   #  Using List Comprehensions
mat2 = [ [ 0 ] * 4 ] * 4                                              # Using multiplying list elements


print( mat1 == mat2 )                         # True

for i in range(4):
    mat1[ i ][ i ]=1                             # mat1 =  [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]
    mat2[ i ][ i ]=1                             # mat2 =  [ [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1] ]


当使用列表元素相乘形成的矩阵时,我哪里做错了? 或者我误导了一些概念

感谢您的解释


谢谢。

这实际上是因为
mat2
包含对相同的4个元素列表的4个引用。在循环的每个步骤中,您都在同一列表中设置一个值

当你说
[0,0,0,0]*4
时,你只是在创建一个包含相同列表四次的列表。这意味着只有两个实际的列表在起作用

当您在[0,1,2,3]]中为i说
[[0,0,0,0]]
时,每次迭代都会创建一个新列表。这意味着有五个实际的列表在起作用

以下代码段应将其可视化:

m1 = [[0 for i in range(4)] for j in range(4)]
m2 = [[0] * 4] * 4

for i in range(4):
    m1[i][i] = 1
    m2[i][i] = 1

    print('m1 at i={}: {}'.format(i, m1))
    print('m2 at i={}: {}'.format(i, m2))
    print('')
产出:

m1 at i=0: [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
m2 at i=0: [[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

m1 at i=1: [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
m2 at i=1: [[1, 1, 0, 0], [1, 1, 0, 0], [1, 1, 0, 0], [1, 1, 0, 0]]

m1 at i=2: [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]]
m2 at i=2: [[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 0]]

m1 at i=3: [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
m2 at i=3: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

这很有趣

mat1 = [ [ 0 for i in range(4) ]  for j in range( 4 ) ]   #  Using List Comprehensions
mat2 = [ [ 0 ] * 4 ] * 4                                              # Using multiplying list elements


print( mat1 == mat2 )                         # True
print( mat1 is mat2 )                         # False

for i in range(4):
    mat1[ i ][ i ]=1                             # mat1 =  [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ]
    mat2[ i ][ i ]=1 
print(mat1是mat2)
的简单测试可以看出,返回的
False
表明变量指向不同的对象。但是
print(mat1==mat2)
返回
True
,如果变量引用的对象相等,则会出现这种情况。因此,在这种情况下,变量是相等的。但是,对象是不同的

mat1
可以看出,实际上是在嵌套循环中循环,但是对于
mat2
来说,实际上是在引用相同的
[0]
数组

基本上可以通过以下操作判断数组是否相乘:

mat1 = [1,2,3]
mat2 = mat1*2
print(mat2)

# outputs
[1,2,3,1,2,3]


噢,输给一个重复的@SamuelWillems是很难的,stackoverflow中没有“赢”或“输”的意思!我只是希望每个人都能通过这个网站学到一些东西:)哈哈,当然