如何强制Python字典缩小?

我已经在其他语言中体验过。 现在我在Python中遇到了同样的问题。 我有一个有很多CRUD操作的字典。 人们会假设从字典中删除元素应该减少它的内存占用量。 情况并非如此。 一旦字典大小增加(通常加倍),它永远不会(?)释放分配的内存。 我已经运行了这个实验:

import random
import sys
import uuid

a= {}
for i in range(0, 100000):
    a[uuid.uuid4()] = uuid.uuid4()
    if i % 1000 == 0:
        print sys.getsizeof(a)

for i in range(0, 100000):
    e = random.choice(a.keys())
    del a[e]
    if i % 1000 == 0:
        print sys.getsizeof(a)

print len(a)

第一个循环的最后一行是6291736 。 第二个循环的最后一行也是6291736 。 字典的大小是0

那么如何解决这个问题呢? 有没有办法强制释放内存?

PS:真的不需要做随机 - 我玩了第二个循环的范围。


要做到这一点的方式是“重新哈哈哈”,所以它使用更少的内存就是创建一个新的字典并复制内容。

Python视频字典的实现在这个视频中得到了很好的解释:

https://youtu.be/C4Kc8xzcA68

有一位同事问这个问题(https://youtu.be/C4Kc8xzcA68?t=1593),发言者的回答是:

调整大小只能在插入时计算; 随着字典的缩小,它只会获得大量的虚拟条目,并且在你重新填充时它将开始重用它们来存储密钥。 [...]您必须将键和值复制到新的字典中


实际上,字典可以在调整大小时缩小,但调整大小只发生在不移除关键插入的情况下。 以下是来自CPython的dictresize源代码的dictresize

通过分配新表并重新插入所有项来重构表。 当条目被删除时,新表可能实际上比旧的表小。

顺便说一下,由于其他答案引用Brandon Rhodes在PyCon 2010上的字典中进行了讨论,并且该引用似乎与上述内容(已存在多年)不一致,因此我认为我将包括完整引用缺少粗体部分。

调整大小仅在插入时计算。 随着字典缩小,它只会获得大量虚拟条目,并且在您重新填充时,它将开始重新使用这些条目来存储密钥。 它不会重新调整大小,直到您将它的三分之二再次放大为止。 所以它不会在您删除密钥时调整大小。 你必须做一个插入才能弄清楚它需要缩小。

所以他说,调整大小操作可以“弄清楚字典需要缩小”。 但是,这只发生在插入。 显然,在调整大小时复制所有键时,虚拟键可以被删除,从而减小了后备阵列的大小。

然而,目前还不清楚如何做到这一点,这就是为什么罗德斯说,只是把所有东西都复制到一本新字典中。

链接地址: http://www.djcxy.com/p/27471.html

上一篇: How to force Python dictionary to shrink?

下一篇: Unable to open native connection with spark sometimes