python中嵌套列表的意外行为

时间:2015-06-02 04:32:41

标签: python list

我有一个名为basic的嵌套列表,我想更改其中一个条目。我承担了以下行为:

expected = [ [9],[0] ]
unexpected = [ [9],[9] ]
basic = [ [0],[0] ]
basic[0][0] = 9
print(basic == expected) # this is true

然而,略微修改会产生令人惊讶的输出:

l = [0]
modified = [ l, l ]
modified[0][0] = 9
print(modified == expected) # this is false
print(modified == unexpected) # this is true

如果您的列表是以第二种方式定义的,则赋值将整列设置为9.

这种行为是否符合设计要求?如果是这样,为什么?我在文档中找不到任何关于它的内容。

1 个答案:

答案 0 :(得分:7)

在你的第一个例子中:

basic = [ [0],[0] ]

您已创建包含两个不同列表对象的列表对象。您可以通过id()或标识:

看到它们是不同的对象
assert id(basic[0]) != id(basic[1])

assert basic[0] is not basic[1]

在你的第二个例子中:

l = [0]
modified = [ l, l ]

您已将相同的列表对象放入另一个列表中两次。两个列表标记都指向同一个对象:

assert id(basic[0]) == id(basic[1])

assert basic[0] is basic[1]

所以,是的。这就是变量(以及它们指向的对象)在Python中的工作方式。

要获得预期的行为,您需要创建单独的列表对象:

modified = [ l.copy(), l.copy() ]