Python - 动态嵌套列表
我正在尝试在Python中根据宽度和高度生成一个嵌套列表。到目前为止,我的代码是这样的:
width = 4
height = 5
row = [None]*width
map = [row]*height
现在,这显然还不太对。当我打印出来时,看起来没问题:
[[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None],
[None, None, None, None]]
但是当我尝试像这样给某个位置赋值时:
map[2][3] = 'foo'
我得到了:
[[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo'],
[None, None, None, 'foo']]
显然,这种情况发生是因为每个子列表实际上都只是引用了同一个对象,也就是“行”,所以改变一个,就会改变所有的。所以这是我目前最接近的结果!
我该如何动态生成一个嵌套列表呢?谢谢!
2 个回答
1
我用的类似这样的东西:
w = 5
h = 5
map = []
for i in range(h):
row = []
for j in range(w):
row.append(None)
map.append(row)
print map
map[2][3] = 'foo'
print map
12
当你使用 [row]*height
时,每一行实际上都是指向同一个列表对象。也就是说,row
这个数组的引用在每一行都是重复的,这样一来,修改其中一行就会影响到所有的行。
你可以查看每一行的 id()
,你会发现它们的值都是一样的!
>>> grid = [[None] * width] * height
>>> [id(row) for row in grid]
[148014860, 148014860, 148014860, 148014860, 148014860]
如果你想让 Python 为每一行生成独立但内容相同的列表,可以使用列表推导式。使用 [rowexpr for i in xrange(height)]
时,rowexpr
会在每一行被计算一次。关键是要使用一个每次计算都会生成独特列表的表达式。
如果你看到实际效果会更容易理解:
>>> grid = [[None] * width for i in xrange(height)]
>>> grid[2][3] = 'foo'
>>> grid
[[None, None, None, None],
[None, None, None, None],
[None, None, None, 'foo'],
[None, None, None, None],
[None, None, None, None]]
每次计算 [None] * width
时,它都会生成一个新的列表。
>>> [id(row) for row in grid]
[148016172, 148015212, 148016236, 148016108, 148016332]