所以我试图根据宽度和高度在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']]
显然,这是因为每个子列表实际上只是引用同一个对象,行,所以更改一个,更改它们。所以这是我最接近的!
如何动态生成嵌套列表?谢谢!
答案 0 :(得分:11)
执行[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]
答案 1 :(得分:0)
我使用这样的东西:
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