我正在尝试访问Python中列表列表的特定元素。我带来了一些C / Java包袱并将此数据结构视为2D数组。在我看来,下面的操作应该只影响第一个列表的第一项,Java中的loc1[0][0]
。实际上,每个子列表的第一项都会受到影响,即loc1[0][0]
,loc1[1][0]
和loc1[2][0]
。知道为什么会这样吗?
def move(loc, dir, nrows, ncols):
loc1 = [[0.0] * ncols] * nrows
for col in range(1):
for row in range(1):
loc1[row][col] += 100.0 * loc[row][col]
return loc1
nrows = 4
ncols = 3
p = [[1.0 / (ncols * nrows)] * ncols] * nrows #uniform prior
print p
p = move(p, [0, 1], nrows, ncols)
print p
答案 0 :(得分:4)
我之前已经发生过这种情况,令人沮丧。
你的问题是这行代码,它没有按照你的想法行事:
loc1 = [[0.0] * ncols] * nrows
[0.0] * ncols
创建一个列表,通过引用传递以形成您的2D列表。
试试这个:
loc1 = [[0.0 for y in range(ncols)] for x in range(nrows)]
答案 1 :(得分:3)
[x]*n
生成的列表包含完全相同的x
元素n
次。
L = [0.0] * ncols
有效,因为0.0
是一个浮点数,浮点数在Python中是不可变的,因此L[0] += 1.1
不会更改0.0
,而是将1.1
放在其位置。
列表是可变的,因此当您更改L = [[0]*ncol]*nrow
中的任何行时,您更改了所有行,因为它是同一个对象。
要修复它,你可以:
L = [[0.0]*ncols for _ in xrange(nrows)]
它为每一行创建一个 new 列表,以便您可以单独更改它们。
或者:
from itertools import repeat
L = [[0.0]*ncols for _ in repeat(None, nrows)]
对你来说更具可读性。