【问题标题】:Why does the id of python dict remains unchanged?为什么python dict的id不变?
【发布时间】:2020-07-28 18:34:07
【问题描述】:

我们有一个像这样的字典:

a = dict()

然后我们插入项目,例如:

for i in range(10**10):
    a[i] = 0

为什么即使字典太大而无法重新分配内存,id(a) 仍保持不变?

【问题讨论】:

  • 无论大小,对象都是一样的,对吧?所以,id 不会改变
  • dict对象还是一样的,不管底层内存如何。
  • 这实际上是我认为的一个好问题,我不明白反对意见。我认为这可能与 id 仅在 CPython 中对应于内存中对象的地址这一事实有关(参见 here
  • 我同意@Djib2011 但它实际上甚至不是 CPython 的东西。无论是否是内存中的地址,[it] 都保证在其生命周期内对于该对象是唯一且常量
  • 我同意,我不明白为什么这被否决了,这个问题很好,为了正确回答你需要有关内部实现的适当知识......其他答案将只是微不足道,浅薄或明显......在这个routine中,内存分配发生在哪里? +1 来自新贡献者的一个非常好的问题:P

标签: python


【解决方案1】:

让我们首先引用 python docs 状态关于 id 内置函数的内容:

id(对象) 返回对象的“身份”。这是一个整数 保证在此对象期间是唯一且恒定的 它的生命周期。两个生命周期不重叠的对象可能有 相同的 id() 值。

CPython implementation detail: 这是对象的地址 记忆。

要了解您的 sn-p:

a = dict()
for i in range(10**10):
    a[i] = 0 

您需要首先了解a = dict() 行发生了什么,在这种情况下,您创建一个新的python 字典对象并将其分配给变量a,此时如果我们参考文档部分谈论@ 987654329@ 在对象的整个生命周期中保持唯一性,一切都应该有意义。例如,假设我们有这个:

a = dict()
print(id(a))
a = dict() # New object
print(id(a))

您可以清楚地看到 id(a) 应该如何更改,这主要是因为第二次分配给a 的对象不一样。另一个例子:

a = dict() # id1
b = dict() # id2
a = b      # id2

同样,您创建了 2 个 dict 对象,在第三个赋值 a=b 中,id(a) 将是 id2,在变量 a 和 @ 引用的对象的生命周期内将保持唯一987654337@

现在,您问题中有趣的部分是您想知道为什么即使您向字典中插入新项目,aid 也不会改变。要了解即使底层内存对象最终会在 __setitem__ 被调用时(底层 cpython 实现 here)和 resized 以特定的增长率发生变化,您也需要注意id 提供的语句docs 将在对象生命周期内保持不变,并且 id 将是唯一的。

【讨论】:

  • 感谢您的回答,它是如此的春天。这是我的第一个问题,所以我的描述很不清楚,下次我会改进这个。事实上,我想知道的是,在 python 中,函数 id() 是对象在内存中的地址,那么为什么 dict 对象变得太大,并重新分配内存。但是仍然具有相同的 id(意思是相同的地址?),这很有趣。
  • 可能这个答案接近link,但我不确定。
  • 那很好:) ...起初,当我开始提问时,我的问题很可怕,现在稍微好一点,但我仍然会发现自己收到很多反对票 ;) 。确保您阅读了https://stackoverflow.com/help/minimal-reproducible-example 链接,这将帮助您改进未来的问题。关于当前的问题,我的回答是否解决了您的问题?如果是这样,请考虑将其标记为有效
猜你喜欢
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2010-12-29
  • 1970-01-01
  • 2011-04-27
相关资源
最近更新 更多