为什么删除后不会调整字典大小?

时间:2017-08-02 20:17:33

标签: python dictionary python-internals

显然删除字典中的条目不会触发任何调整大小。只有在添加条目后才会触发调整大小。

这可以从以下内容中看出:

# Drastic example, nobody does such 
# things with dicts FWIK
from sys import getsizeof

d = {i:i for i in range(100)}
print(getsizeof(d))  # 4704
for i in range(100):
    del d[i]  # similarly with pop
print(getsizeof(d))  # 4704
d[0] = 1 # triggers resize

以及a question on SO(来自我发现的内容)。 set的行为方式类似,预计会与dicts的行为一致。

另一方面,

list,当新大小变为已分配的大小的一半时,调整大小;这在list_resize comment

中说明
/* Bypass realloc() when a previous overallocation is large enough
   to accommodate the newsize.  If the newsize falls lower than half
   the allocated size, then proceed with the realloc() to shrink the list.
*/

为什么字典(以及间接设置)不使用类似的技巧而是等待插入新条目?所描述的行为适用于Python 2.7和3.x(直到Python 3.7.0a0)。

1 个答案:

答案 0 :(得分:12)

这在Objects/dictnotes.txt中有所解释,这是一个配套文件,包含有关dict实现的各种注释:

  

只涉及单个键的字典操作可以是O(1),除非   调整大小是可能的。通过检查仅在调整大小时   其他操作可以增长字典(并且可以要求调整大小)   保持O(1),以及调整大小抖动或内存碎片的几率   减少了。特别是,一种通过排空字典的算法   反复调用.pop将看不到调整大小,这可能不是   因为字典最终被丢弃所以是必要的   完全。

一个重要的考虑因素是缩小列表的缓冲区非常简单,而缩小dict的内部哈希表则是一个复杂得多的操作。