创建填充相同值的列表列表

时间:2017-09-28 20:56:44

标签: python python-3.x

我尝试创建一个包含多个列表的列表,这些列表以这种方式填充相同的值:

l1 = [[False] * n] * m

没有任何错误,乍一看它看起来像列表的有效列表(print(l1) for n=m=3 : [[False,False,False],[False,False,False],[False,False,False]]

但是当我尝试l1[0][0] = True时,我得到了一个奇怪的行为 - 列表已变为[[True,False,False],[True,False,False],[True,False,False]]

那么,为什么这样的列表初始化结果呢?我该怎么做才能正确创建一个列表?

2 个答案:

答案 0 :(得分:3)

l1 = [[False] * n] * m
# I assume this is what you did, since 
# [False * 3] == [0], and not [False, False, False]

采用相同 list个实例[False * n] m次。更改对所述实例的一个引用将影响所有引用。使用理解来创建独立列表:

l1 = [[False] * n for _ in range(m)]

应该注意这是有效的,因为bool是不可变类型。如果你有一个可变类型,让我们说X,你也必须使用对内部列表的理解:

l1 = [[X() for _ in range(n)] for _ in range(m)]

答案 1 :(得分:2)

那是因为实际上只有一个嵌套列表。您在外部列表中看到的实际上是三个引用实际上是相同的列表。

如果您使用自定义对象,则可以轻松地观察到这一点:

class MyClass:
    def __init__(self):
        pass

a = MyClass()
l = [[a] * 2]

打印l会产生以下输出:

[<__main__.MyClass object at 0x000000000462A2E8>, <__main__.MyClass object at 0x000000000462A2E8>]

注意内存地址是如何相同的,因为它是同一个对象。它只是在列表中引用了两次。通过一个索引修改它与通过另一个或直接修改它相同。更改它会随处更新。

同样,当您通过执行l1[0][0] = True修改嵌套列表时,对列表对象的所有引用都会更新,从而导致您看到的内容。