我对set
s 的这种内存分配行为感到困惑:
>>> set(range(1000)).__sizeof__()
32968
>>> set(range(1000)).union(range(1000)).__sizeof__() # expected, set doesn't change
32968
>>> set(range(1000)).union(list(range(1000))).__sizeof__() #expected, set doesn't change
32968
>>> set(range(1000)).union(set(range(1000))).__sizeof__() # not expected
65736
为什么使用set
as 参数会使结果使用的内存量加倍set
?两种情况下的结果都与原始结果相同set
:
>>> set(range(1000)) == set(range(1000)).union(range(1000)) == set(range(1000)).union(set(range(1000)))
True
请注意,使用普通迭代器也会发生同样的情况:
>>> set(range(1000)).union(iter(list(range(1000)))).__sizeof__()
32968
并使用以下update
方法:
>>> a.update(range(1000))
>>> a.__sizeof__()
32968
>>> a.update(set(range(1000)))
>>> a.__sizeof__()
65736
起初我以为是因为当union
被调用时,它看到另一个的大小set
是1000
,因此决定分配足够的内存来容纳两个set
s 的所有元素,但后来它只使用了该内存的一部分,而在迭代器情况下,它只是对其进行迭代并逐个添加元素(这不会消耗更多内存,因为所有元素都已经在set
.
但是range
也是一个序列,list
第一个例子中的也是。
>>> len(range(1000))
1000
>>> range(1000)[100]
100
那么为什么这不会发生,range
而list
只是发生set
呢?这背后是否有任何设计决策,或者它是一个错误?
在 linux 64 位上的 python 2.7.3 和 python 3.2.3 上测试。