创建列表列表时python参考行为的说明

时间:2019-03-20 14:37:19

标签: python python-3.x memory reference

通过以下方式创建新的嵌套列表时:

test_list = [[""]]*5

发生意外行为,将以下修改附加到索引:

test_list[1].append(2)
[['', 2], ['', 2], ['', 2], ['', 2], ['', 2]]

当执行以下操作时,它会按我期望的那样工作:

test_list[1] = test_list[1] + [0]
[[''], ['', 0], [''], [''], ['']]

但是当使用+ =运算符时,会发生同样的事情

test_list[1] += [0]
[['', 0], ['', 0], ['', 0], ['', 0], ['', 0]]

当列表定义如下时:[[""] for i in range(len(5))]所有示例都返回预期的输出。

这是怎么回事?是我不理解的参考资料吗?

2 个答案:

答案 0 :(得分:2)

通过使用test_list = [[""]] * 5,您将创建5个对同一列表的引用。这意味着内存中只有只有一行

修改行时,如果影响到内存中的行,并且由于所有其他“行”都引用了该行,则它们将仅使用最新的内存中的列表。

但是这会在内存中创建5个列表的列表:

test_list = [[""] for i in range(len(5))]

================================================ ==========================

您可以找到一个example and explanation in wtfpython

# Let's initialize a row
row = [""]*3 #row i['', '', '']
# Let's make a board
board = [row]*3

输出:

>>> board
[['', '', ''], ['', '', ''], ['', '', '']]
>>> board[0]
['', '', '']
>>> board[0][0]
''
>>> board[0][0] = "X"
>>> board
[['X', '', ''], ['X', '', ''], ['X', '', '']]

说明:

初始化row变量时,此可视化解释了内存中发生的情况。

enter image description here

board通过乘以row进行初始化时,这就是内存内部发生的情况(每个元素board[0]board[1]和{{1} }是对board[2]所引用的同一列表的引用

enter image description here

我们可以通过不使用row变量来生成row来避免这种情况。 (在this问题中提出)。

board

答案 1 :(得分:1)

您正在创建一个包含五个指向同一列表的元素的列表。

调用test_list[1].append(2)时,它会将数字2附加到列表中,然后将其附加到所有列表中。

调用test_list[1] = test_list[1] + [0]时,将创建一个列表的新实例,并将其分配给test_list[1]。现在,索引1中的列表与其他所有列表4都不相同。

在这里,test_list[1] += [0]+=会转换为test_list[1].append(0),它会将零添加到所有列表中。

了解test_list[1] = test_list[1] + [0]的示例:

lst = [0]
print(lst) 
# output: [0]

lst += [1]
print(lst) 
# output: [0, 1]

lst.append(2)
print(lst) 
# output: [0, 1, 2]

lst2 = lst + [3]
print(lst) 
# output: [0, 1, 2]
# the lst did not change!

print(lst2) 
# output: [0, 1, 2, 3]
# a new instance of a list which is not lst

现在,让我们看一下元素的对象ID:

test_list = [[""]]*5
print(test_list)
# output: [[''], [''], [''], [''], ['']]

for i in range(5):
    object_id = id(test_list[i])
    print(object_id)
# output: 4405988168
# output: 4405988168
# output: 4405988168
# output: 4405988168
# output: 4405988168

test_list[1] = test_list[1] + [0]
print(test_list)
# output: [[''], ['', 0], [''], [''], ['']]

for i in range(5):
    object_id = id(test_list[i])
    print(object_id)
# output: 4405988168
# output: 4417503368     !!!!
# output: 4405988168
# output: 4405988168
# output: 4405988168