Python - 动态嵌套列表

Diz*_*Doo 6 python nested list

所以我试图根据宽度和高度在Python中生成嵌套列表.这是我到目前为止:

    width = 4
    height = 5
    row = [None]*width
    map = [row]*height
Run Code Online (Sandbox Code Playgroud)

现在,这显然不太正确.打印时看起来很好:

[[None, None, None, None],
 [None, None, None, None],
 [None, None, None, None],
 [None, None, None, None],
 [None, None, None, None]]
Run Code Online (Sandbox Code Playgroud)

但是尝试将值分配给这样的位置:

map[2][3] = 'foo'
Run Code Online (Sandbox Code Playgroud)

我明白了:

[[None, None, None, 'foo'],
 [None, None, None, 'foo'],
 [None, None, None, 'foo'],
 [None, None, None, 'foo'],
 [None, None, None, 'foo']]
Run Code Online (Sandbox Code Playgroud)

很明显,这是因为每个子列表实际上只是引用相同的对象,行,所以更改一个,更改它们.所以这是我最接近的!

如何动态生成嵌套列表?谢谢!

Joh*_*ica 11

当你这样做[row]*height时,每行最终都有相同的列表对象.将row数组引用被重复,这意味着每行实际上是指向同一个列表对象的每一行英寸 因此,修改一行实际上会修改所有行.

看看id()每行打印时会发生什么.他们都是一样的!

>>> grid = [[None] * width] * height
>>> [id(row) for row in grid]
[148014860, 148014860, 148014860, 148014860, 148014860]
Run Code Online (Sandbox Code Playgroud)

您可以使用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]]
Run Code Online (Sandbox Code Playgroud)

每次[None] * width评估它都会生成一个新列表.

>>> [id(row) for row in grid]
[148016172, 148015212, 148016236, 148016108, 148016332]
Run Code Online (Sandbox Code Playgroud)