0

可能重复:
Python 列表中的意外功能

我有一个用 9 x 11 的 0 填充的矩阵。我想让每行的第一个元素和每列的第一个元素的得分比前一个小 -2,所以:

[[0, -2, -4], [-2, 0, 0], [-4, 0, 0]]

为此,我使用以下代码:

# make a matrix of length seq1_len by seq2_len filled with 0's\
x_row = [0]*(seq1_len+1)
matrix = [x_row]*(seq2_len+1)
# all 0's is okay for local and semi-local, but global needs 0, -2, -4 etc at first elmenents
# because of number problems need to make a new matrix
if align_type == 'global':
    for column in enumerate(matrix):
        print column[0]*-2
        matrix[column[0]][0] = column[0]*-2
for i in matrix:
    print i

结果:

0
-2
-4
-6
-8
-10
-12
-14
-16
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

为什么它将 column[0]*-2 的最后一个值提供给所有行?

4

2 回答 2

3

尝试运行此代码:

x_row = [0]*(seq1_len+1)

matrix = [x_row]*(seq2_len+1)

matrix[4][5]=5

print matrix

您会看到 5 已经扩散。这是因为第二行代码复制了相同的数据。看到这个

列表更改意外地反映在子列表中

于 2012-11-01T11:31:15.010 回答
1

这是因为您创建列表列表的方式实际上会产生一个列表,其中包含相同的列表对象,即相同id(),更改一个实际上也会改变其他列表:

In [4]: x_row = [0]*(5+1)

In [5]: matrix = [x_row]*(7+1)

In [6]: [id(x) for x in matrix]
Out[6]:                         #same id()'s, means all are same object
[172797804,
 172797804,
 172797804,
 172797804,
 172797804,
 172797804,
 172797804,
 172797804]

In [20]: matrix[0][1]=5 #changed only one

In [21]: matrix         #but it changed all
Out[21]: 
[[0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0],
 [0, 5, 0, 0, 0, 0]]

您应该以这种方式创建矩阵以避免这种情况:

In [12]: matrix=[[0]*6 for _ in range(9)]

In [13]: [id(x) for x in matrix]
Out[13]:                           #different id()'s, so different objects 
[172796428,              
 172796812,
 172796364,
 172796268,
 172796204,
 172796140,
 172796076,
 172795980,
 172795916]

In [23]: matrix[0][1]=5  #changed only one

In [24]: matrix         #results as expected
Out[24]: 
[[0, 5, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0]]
于 2012-11-01T11:28:09.010 回答