【问题标题】:Why does this empty dict break shared references?为什么这个空字典会破坏共享引用?
【发布时间】:2015-07-09 05:43:48
【问题描述】:

我发现了一些让我困惑的 Python 行为。

>>> A = {1:1}
>>> B = A
>>> A[2] = 2
>>> A
{1: 1, 2: 2}
>>> B
{1: 1, 2: 2}

到目前为止,一切都按预期运行。 A 和 B 都引用相同的、可变的字典,并且更改一个会更改另一个。

>>> A = {}
>>> A
{}           # As expected
>>> B
{1: 1, 2: 2} # Why is this not an empty dict?

为什么AB 不再引用同一个对象?

我看到了这个问题:Python empty dict not being passed by reference?,它验证了这种行为,但答案解释了如何修复提供的脚本而不是为什么会发生这种行为。

【问题讨论】:

  • Assignment 将名称绑定到对象。它不会改变对象。

标签: python dictionary pass-by-reference


【解决方案1】:

这是一个图示*:

A = {1: 1} 
# A -> {1: 1}
B = A
# A -> {1: 1} <- B
A[2] = 2
# A -> {1: 1, 2: 2} <- B
A = {}
# {1: 1, 2: 2} <- B    
# A -> {}

A = {} 创建一个全新的对象,并将标识符A 重新分配给它,但影响B 或先前引用的字典A .你应该阅读this article,它很好地涵盖了这类事情。


请注意,作为替代方案,您可以使用dict.clear 方法就地清空字典

>>> A = {1: 1}
>>> B = A
>>> A[2] = 2
>>> A.clear()
>>> B
{}

由于AB 仍然是对同一个对象的引用,现在两者都“看到”了空版本。


* 第一个近似值 - 类似的引用行为也发生在 字典中,但由于值是不可变的,因此相关性较低。

【讨论】:

  • 啊比我的解释好多了:P 这个人有办法:)
  • @JoranBeasley 好吧...图片!
  • 一张照片值一千个字。
【解决方案2】:

这样想:A 是一个对象的名称,然后您为该对象指定 B 的不同名称。这是第一部分,但是在第二个代码中,您创建了一个新对象并说好的,旧对象不再称为 A,现在这个新对象称为 A。

B 没有指向 A。B 和 A 都是同一个对象的名称,然后是两个不同对象的名称。

【讨论】:

    【解决方案3】:

    请记住,python 中的变量就像标签一样。因此,在第一个示例中,您有一个字典 {1:1, 2:2}。那本字典留在记忆中。在第一个例子中,A 指向那个字典,你说 B 指向 A 指向的东西(它不会指向标签 A,而是标签 A 指向的东西)。

    在第二个示例中,A 和 B 都指向该字典,但您将 A 指向一个新字典 ({})。 B 一直指向第一个示例中内存中的旧字典。

    【讨论】:

      【解决方案4】:

      这是关于创建新字典和更改现有字典之间的区别。

      A[2] = 2
      

      正在通过添加新键来修改字典,现有内容仍然是该字典的一部分。

      A = {}
      

      这会创建一个全新的空字典。

      【讨论】:

        【解决方案5】:

        当您说 A={} 时,您正在更改 A 指向的字典,而不是破坏旧字典...此示例应该为您演示

        A={1:1} 
        print id(A)
        B = A
        print id(B)
        B[2] = 5
        print id(B)
        print A
        print id(A)
        A = {}
        print id(A)
        

        【讨论】:

          猜你喜欢
          • 2016-08-16
          • 1970-01-01
          • 2011-07-23
          • 2021-05-27
          • 2019-12-11
          • 2012-10-08
          • 2011-11-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多