2017-10-09 152 views
0

为什么矩阵填充了像这样的namedtuples?使用namedtuples填充矩阵

正确插入索引

,以及如何解决它?

from collections import namedtuple 

Point = namedtuple('Point', ['x', 'y']) 
m, n = 3, 3 
matrix = [[None] * n] * m 
for i in range(m): 
    for j in range(n): 
     matrix[i][j] = Point(i, j) 
for row in matrix: 
    print(row) 

#>>Output 
#[Point(x=2, y=0), Point(x=2, y=1), Point(x=2, y=2)] 
#[Point(x=2, y=0), Point(x=2, y=1), Point(x=2, y=2)] 
#[Point(x=2, y=0), Point(x=2, y=1), Point(x=2, y=2)] 

结果应该是

#>>Output 
#[Point(x=0, y=0), Point(x=0, y=1), Point(x=0, y=2)] 
#[Point(x=1, y=0), Point(x=1, y=1), Point(x=1, y=2)] 
#[Point(x=2, y=0), Point(x=2, y=1), Point(x=2, y=2)] 

回答

2

因为[] * m正在同一列表的m副本(他们正在引用相同的列表)。所以当你改变其中一个时,它会改变它们。 因此,在最后一行,最后一行将覆盖您之前填写的任何值。

更改您的初始化为matrix = [[[None] for i in range(n)] for j in range(m)],它会工作得很好。

这里的another StackOverflow answer展示了以这种方式初始化二维数组的副作用。

0

我不知道为什么,但低于工程代码及以上不

for k in range(m): 
    matrix[k] = [Point(k, i) for i in range(n)] 
+0

f你有m,n = 4,3会出现错误 – Vartan

+0

不,我从来不会伤心离开init矩阵。 matrix still matrix = [[None] * n] * m –

+0

对不起,你是对的 – Vartan

0

如果打印x和y与显示功能,您将看到通过使用comperhensions在同一

from collections import namedtuple 

Point = namedtuple('Point', ['x', 'y']) 
m, n = 3, 3 
matrix = [[None] * n] * m 

for i in range(m): 
    for j in range(n): 
     p = Point(x=i, y=j) 
     matrix[i][j] = p 

     print(id(p.x)) 
     print(id(p.y)) 

尝试引用。

for i in range(m): 
    matrix[i] = [Point(i, j) for j in range(n)] 

for row in matrix: 
    print(row)`