2D 列表在尝试修改单个值 [duplicate] 时具有奇怪的行为

2D list has weird behavor when trying to modify a single value [duplicate]

提问人:Brian 提问时间:4/30/2010 最后编辑:Karl KnechtelBrian 更新时间:1/15/2023 访问量:36190

问:

当我尝试此代码时:

data = [[None]*5]*5
data[0][0] = 'Cell A1'

的值如下所示:data

[['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None]]

为什么该值出现在每个嵌套列表中?'Cell A1'

python list 嵌套列表

评论


答:

122赞 Mark Byers 4/30/2010 #1

这将创建一个列表,其中包含对同一列表的五个引用:

data = [[None]*5]*5

请改用类似这样的东西,这将创建五个单独的列表:

>>> data = [[None]*5 for _ in range(5)]

现在它的行为符合预期:

>>> data[0][0] = 'Cell A1'
>>> print(data)
[['Cell A1', None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None]]
2赞 lfagundes 4/30/2010 #2

在 Python 中,每个变量都是一个对象,因此也是一个引用。您首先创建了一个包含 5 个 s 的列表,然后构建了一个包含 5 倍相同对象的列表。None

20赞 mmmmmm 4/30/2010 #3

序列类型(包括列表)的文档中所述:

另请注意,副本很浅;不会复制嵌套结构。这经常困扰着新的 Python 程序员;考虑:

>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]

发生的情况是,这是一个包含空列表的单元素列表,因此所有三个元素都是(指向)这个空列表的指针。修改 的任何元素都会修改此单个列表。您可以通过以下方式创建不同列表的列表:[[]][[]] * 3lists

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]