【问题标题】:Are Python Lists mutable?Python 列表是可变的吗?
【发布时间】:2014-08-09 03:21:35
【问题描述】:

当我输入以下代码时,

x=[1,2,4]
print(x)
print("x",id(x))
x=[2,5,3]
print(x)
print("x",id(x))

输出为

[1, 2, 4]
x 47606160
[2, 5, 3]
x 47578768

如果列表是可变的,那么为什么在更改列表 x 时它会给出 2 个内存地址?

【问题讨论】:

  • @iCodez 的答案是正确的。您应该仔细阅读 Python 文档的 "Naming and Binding" section,它准确地解释了 Python 执行赋值语句时发生的情况,variable_name = ...

标签: python list mutable


【解决方案1】:

您创建了一个新列表对象,并将其绑定到同名x。您从未在开始时改变绑定到 x 的现有列表对象。

Python 中的名称只是引用。赋值是将名称绑定到对象。当您再次分配给x 时,您将该引用指向不同的对象。在您的代码中,您只需创建一个全新的列表对象,然后将x 绑定到该新对象。

如果你想改变一个列表,调用那个对象的方法:

x.append(2)
x.extend([2, 3, 5])

或分配给列表的索引或切片:

x[2] = 42
x[:3] = [5, 6, 7]

演示:

>>> x = [1, 2, 3]
>>> id(x)
4301563088
>>> x
[1, 2, 3]
>>> x[:2] = [42, 81]
>>> x
[42, 81, 3]
>>> id(x)
4301563088

我们更改了列表对象(对其进行了变异),但该列表对象的id() 没有更改。它仍然是同一个列表对象。

也许 Ned Batchelder 关于 Python 名称和绑定的精彩演示会有所帮助:Facts and myths about Python names and values

【讨论】:

    【解决方案2】:

    您没有使用此行改变(更改)x 引用的列表对象:

    x=[2,5,3]
    

    相反,该行创建了一个新列表对象,然后将变量x 重新分配给它。所以,x 现在引用了新对象,id(x) 给出了一个与以前不同的数字:

    >>> x=[1,2,4]  # x references the list object [1,2,4]
    >>> x
    [1, 2, 4]
    >>> x=[2,5,3]  # x now references an entirely new list object [2,5,3]
    >>> x
    [2, 5, 3]
    >>>
    

    【讨论】:

    • 感谢您的解释。但是我发现很难理解为什么 x=2*x 创建一个新对象并将 x 绑定到它,而不是仅仅改变原始对象。 x.append 类似。如果我写x.append,那么地址保持不变,但如果我写x2=x.append,那么x2 指向一个新对象。 (我不能写x=x.append 因为append() 不会返回新列表)我想我需要完全理解赋值语义。
    【解决方案3】:

    您没有改变列表,您正在创建一个新列表并将其分配给名称x。这就是id 为您提供不同输出的原因。您的第一个列表已经消失,将被垃圾收集(除非某处有另一个引用)。

    【讨论】:

      猜你喜欢
      • 2014-08-03
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多