【问题标题】:Why does 'append' mutates all elements in a list? [duplicate]为什么“追加”会改变列表中的所有元素? [复制]
【发布时间】:2014-01-02 01:55:22
【问题描述】:

我正在构建一个列表列表。我正在从输入文件中读取元素。我正在阅读每个 文件中的行作为字符串单个元素到列表中的子列表。首先,我创建了 列表列表:

>>> b = [[]] * 5

但是,当我尝试附加一个项目时,我得到了以下信息:

>>> b[1].append("abc")
>>> b
[ ['abc'], ['abc'], ['abc'], ['abc'], ['abc'])

为什么append 会更改所有子列表?在这种情况下insert() 更好吗?

【问题讨论】:

标签: python list


【解决方案1】:

当您执行 [[]] * 5 时,它是重复 5 次的相同对象列表(此处为空列表)。

您可以通过以下方式查看:

>>> b = [[]] *5

>>> b
[[], [], [], [], []]

>>> id(b[0])
140588316211896

>>> id(b[1])
140588316211896

你需要做的是:

>>> b = [[] for i in range(5)]
>>> b[0].append('abc')
>>> b
[['abc'], [], [], [], []]

对于[[] for i in range(5)],在每个循环中都会创建一个新的空列表对象。

在这里插入不是一个好的选择,因为插入是一个O(n) 操作,而附加是O(1)

【讨论】:

  • 您能否解释一下为什么您的解决方案有效,为什么在您的灵魂中,这些列表不是同一个对象?
  • @idish:因为在每个循环中都会创建一个新的空列表对象。
  • @Ankur 你怎么知道 insert() 是 O(n) 和 append O(1)?
  • @Dombey:你可以在这里查看各种python方法的时间复杂度:wiki.python.org/moin/TimeComplexity
【解决方案2】:

当你说

b = [[]] * 5

它创建了 5 个列表,它们都指向同一事物。如果你打印出每个元素的地址,你会发现它们是一样的。

所以不管你是使用append 还是insert

【讨论】:

  • 没有。在幕后,列表主要由对同一唯一列表[ ] 的 5 个引用组成,说列表指向“事物”没有任何意义。一个东西 ?有一个词,它是“对象”。
  • @eyquem 是的,说它是一个列表列表是不准确的,但我认为将它称为“事物”或“对象”之间并没有太大区别.
【解决方案3】:

这是一个常见问题解答。所有 5 个顶级列表元素都指向同一个列表。

看看这个:

#!/usr/local/cpython-3.3/bin/python

if True:
    b = [[] for dummy in range(5)]
else:
    b = [[]] * 5

b[1].append("abc")

print(b)

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2011-09-15
    • 2020-05-02
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多