python中奇怪的二维列表行为

MRa*_*ser 2 python list

为什么python会执行以下操作?

>>> bla = [[]] * 5
>>> bla[3].append("blub")
>>> print bla
[['blub'], ['blub'], ['blub'], ['blub'], ['blub']]
Run Code Online (Sandbox Code Playgroud)

我期待

[[], [], [], ['blub'], []]
Run Code Online (Sandbox Code Playgroud)

Kat*_*iel 5

这是与Python混淆的一个常见问题,与隐式传递引用有关.当你输入

x = []
Run Code Online (Sandbox Code Playgroud)

绑定名称x以指向内存中的空列表.当你这样做

x = [[]] * 5
Run Code Online (Sandbox Code Playgroud)

绑定名称x以指向五个事物的列表,每个事物都是对同一个空列表的引用.如果您这样想的话,这可能会更清楚:

>>> y = []
>>> x = [y]*5
>>> x
[[], [], [], [], []]
>>> x[0].append(0)
>>> x
[[0], [0], [0], [0], [0]]
>>> y
[0]
Run Code Online (Sandbox Code Playgroud)

也就是说,即使[]不绑定任何变量名,它仍会创建对空列表的引用,然后将其复制五次.

如果您不想这样做,则需要显式构造五个空列表来存储x.有很多方法可以做到这一点(copy.deepcopy是一般解决方案),但我认为最好的方法是:

x = [[] for _ in range(5)]
Run Code Online (Sandbox Code Playgroud)

或者,numpy是一个扩展模块,它提供了一个非常强大的多维数组.