首页 文章

为什么foo.append(bar)会影响列表列表中的所有元素? [重复]

提问于
浏览
10

这个问题在这里已有答案:

我创建了一个列表列表,并希望将项目附加到各个列表,但是当我尝试附加到其中一个列表( a[0].append(2) )时,该项目将添加到所有列表中 .

a = []
b = [1]

a.append(b)
a.append(b)

a[0].append(2)
a[1].append(3)
print(a)

给: [[1, 2, 3], [1, 2, 3]]

我希望: [[1, 2], [1, 3]]

改变我构造列表的初始列表的方式,使 b 成为浮点而不是列表并将括号放在 .append() 中,为我提供了所需的输出:

a = []
b = 1

a.append([b])
a.append([b])

a[0].append(2)
a[1].append(3)
print(a)

给: [[1, 2], [1, 3]]

但为什么?结果应该是不同的,这是不直观的 . 我知道这与multiple references to the same list有关,但我不知道发生了什么 .

3 回答

  • 2

    关键是这部分:

    a.append(b)
    a.append(b)
    

    您将两次附加相同的列表,因此 a[0]a[1] 都是对同一列表的引用 .

    在第二个示例中,每次调用append时都会创建新列表,如 a.append([b]) ,因此它们是使用相同浮点值初始化的单独对象 .

  • 1

    这是因为列表包含对象的引用 . 您的列表不包含 [[1 2 3] [1 2 3]] ,它是 [<reference to b> <reference to b>] .

    当您更改对象时(通过将某些内容附加到 b ),您将更改对象本身,而不是包含该对象的列表 .

    为了获得您想要的效果,列表 a 必须包含 b 的副本,而不是对 b 的引用 . 要复制列表,您可以使用 [:] 范围 . 例如, :

    >>> a=[]
    >>> b=[1]
    >>> a.append(b[:])
    >>> a.append(b[:])
    >>> a[0].append(2)
    >>> a[1].append(3)
    >>> print a
    [[1, 2], [1, 3]]
    
  • 22

    为了制作列表的浅表副本,这个成语是

    a.append(b[:])
    

    当加倍时会导致a有两个新的列表 b 的副本,它们不会给你报告的别名错误 .

相关问题