所以我在玩list
对象时发现了一个小奇怪的现象,如果list
是用list()
创建的,它使用的内存比列表理解要多?我使用的是python3.5.2
In [1]: import sys
In [2]: a = list(range(100))
In [3]: sys.getsizeof(a)
Out[3]: 1008
In [4]: b = [i for i in range(100)]
In [5]: sys.getsizeof(b)
Out[5]: 912
In [6]: type(a) == type(b)
Out[6]: True
In [7]: a == b
Out[7]: True
In [8]: sys.getsizeof(list(b))
Out[8]: 1008
从docs:
Lists may be constructed in several ways:
- Using a pair of square brackets to denote the empty list:
[]
- Using square brackets, separating items with commas:
[a]
,[a, b, c]
- Using a list comprehension:
[x for x in iterable]
- Using the type constructor:
list()
orlist(iterable)
但似乎使用list()
会占用更多内存。在
当list
越大,间隙越大。在
为什么会这样?在
更新1
使用Python 3.6.0b2进行测试:
^{pr2}$更新2
使用Python 2.7.12进行测试:
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getsizeof(list(xrange(100)))
1016
>>> sys.getsizeof([i for i in xrange(100)])
920
我想你看到的是分配模式这是一个sample from the source:
打印长度为0-88的列表理解的大小可以看到匹配的模式:
^{pr2}$结果(格式为
(list length, (old total size, new total size))
):过度分配是出于性能原因而进行的,允许列表在每次增长时不分配更多内存(更好的amortized性能)。在
与使用列表理解不同的一个可能原因是,列表理解不能确定地计算生成的列表的大小,但是
list()
可以。这意味着,在使用过度分配填充列表时,理解将不断增加列表,直到最终填充为止。在一旦完成,is可能不会增加具有未使用的已分配节点的过度分配缓冲区(事实上,在大多数情况下,它不会,这将破坏过度分配的目的)。在
但是,
list()
可以添加一些缓冲区,不管列表大小如何,因为它预先知道最终的列表大小。在另一个支持性证据(同样来自源代码)是,我们看到了list comprehensions invoking ^{} ,它表示使用
list.resize
,而这又表示在不知道将填充多少预分配缓冲区的情况下使用它。这和你看到的行为是一致的。在总之,
list()
将根据列表大小预先分配更多节点List comprehension不知道列表的大小,因此它在增长时使用append操作,耗尽预分配缓冲区:
感谢大家帮助我理解了那条可怕的Python。在
我不想提出这么大的问题(为什么我要发布答案),只想展示和分享我的想法。在
正如@ReutSharabani正确指出的:“list()决定了列表大小”。从图中可以看出。在
当你
append
或使用列表理解时,你总会有某种边界,当你到达某个点时,这些边界就会延伸。使用list()
你有几乎相同的边界,但是它们是浮动的。在更新
感谢@ReutSharabani,@tavo,@SvenFestersen
总而言之:
list()
根据列表大小预先分配内存,列表理解无法做到这一点(它在需要时请求更多内存,如.append()
)。这就是list()
存储更多内存的原因。在还有一个图,显示
list()
预分配内存。所以绿线显示list(range(830))
一个元素地追加元素,并且在一段时间内内存没有改变。在更新2
正如@Barmar在下面的评论中指出的,},结果是
list()
必须比列表理解快,所以我用number=1000
运行timeit()
,从4**0
到{相关问题 更多 >
编程相关推荐