通过以下方式创建新的嵌套列表时:
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))]
所有示例都返回预期的输出。
这是怎么回事?是我不理解的参考资料吗?
答案 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
变量时,此可视化解释了内存中发生的情况。
当board
通过乘以row
进行初始化时,这就是内存内部发生的情况(每个元素board[0]
,board[1]
和{{1} }是对board[2]
所引用的同一列表的引用
我们可以通过不使用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