Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么';从列表中删除项目时,内存大小是否会改变?_Python_List_Python 2.7 - Fatal编程技术网

Python 为什么';从列表中删除项目时,内存大小是否会改变?

Python 为什么';从列表中删除项目时,内存大小是否会改变?,python,list,python-2.7,Python,List,Python 2.7,是的,为什么从列表中删除一个项目时大小不改变? 有没有办法改变这种行为 Python 2.7.5+ (default, Feb 27 2014, 19:37:08) >>> from sys import getsizeof >>> x = [1, 2, 3, 4] >>> print getsizeof(x), x 104 [1, 2, 3, 4] >>> del x[3] >>> print gets

是的,为什么从列表中删除一个项目时大小不改变?
有没有办法改变这种行为

Python 2.7.5+ (default, Feb 27 2014, 19:37:08) 
>>> from sys import getsizeof
>>> x = [1, 2, 3, 4]
>>> print getsizeof(x), x
104 [1, 2, 3, 4]
>>> del x[3]
>>> print getsizeof(x), x
104 [1, 2, 3]

getsizeof
获取列表对象的内存消耗,而不是其长度或类似的内容。删除项目不会导致列表释放内存,除非删除的项目超过某个阈值;它保留了存储未来项目的内存,降低了分配成本

另外,
getsizeof
不包括列表元素占用的内存,只包括列表头和指针动态数组的内存

如果要修剪内存消耗,请创建列表的切片副本:

>>> x = [1]*3
>>> del x[2]
>>> sys.getsizeof(x)
88
>>> sys.getsizeof(x[:])
80

不过,这通常不是必需的,每次删除都这样做几乎肯定是个坏主意。

getsizeof
获取列表对象的内存消耗,而不是它的长度或类似的内容。删除项目不会导致列表释放内存,除非删除的项目超过某个阈值;它保留了存储未来项目的内存,降低了分配成本

另外,
getsizeof
不包括列表元素占用的内存,只包括列表头和指针动态数组的内存

如果要修剪内存消耗,请创建列表的切片副本:

>>> x = [1]*3
>>> del x[2]
>>> sys.getsizeof(x)
88
>>> sys.getsizeof(x[:])
80

不过,这通常是不必要的,每次删除都这样做几乎肯定是个坏主意。

最好的猜测是,python不会在每次从列表中删除项目时释放列表的末尾。它会保留那个空间一段时间,以防再次需要它。它可能会等到有足够数量的空白空间来保证一次大的清除。

最好的猜测是,python不会在每次从列表中删除一个项目时释放列表的末尾。它会保留那个空间一段时间,以防再次需要它。它可能会等到有足够数量的空白空间来保证一次大扫除。

当你添加一个项目时,它通常也不会改变。这是因为
list
的实现作为一种优化过度分配。除了修改Python的源代码之外,没有其他方法可以更改它。

添加项目时,它通常也不会更改。这是因为
list
的实现作为一种优化过度分配。除了修改Python的源代码之外,没有其他方法可以改变它。

列表对象不会在每次删除时调整内部C数组的大小;那将是非常低效的

相反,在添加元素时,list对象会根据需要定期过度分配新内存,而在删除时,仅当删除的内存足以容纳已分配空间的一半时,才会调整其大小。从C代码:

if(已分配>=newsize&&newsize>=(已分配>>1)){
断言(self->ob_item!=NULL | | newsize==0);
Py_大小(自身)=新闻大小;
返回0;
}
其中,
newsize
是存储的对象引用的实际计数,
allocated
是过度分配的列表对象的大小。当
newsize
仍大于或等于所分配空间的一半时,上述测试将跳过重新分配

即使在缩小列表时,数组仍会被分配过多以接收新元素;列表数组中始终至少有3个插槽为空

因此,
sys.getsizeof()
在删除足够的元素之前保持稳定:

>>> from sys import getsizeof
>>> x = [1, 2, 3, 4] * 3
>>> x
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> print getsizeof(x), x
168 [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> print getsizeof(x), x
168 [1, 2, 3, 4, 1, 2, 3, 4]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> print getsizeof(x), x
136 [1, 2, 3, 4]
在另一个方向上,添加元素时,“列表过度分配”会使列表按与存储的引用数成比例的步长增长:

/*这与列表大小成比例的超额分配,腾出空间
*为了进一步的增长。这种过度分配是温和的,但也很严重
*足以在长期内产生线性时间摊销行为
*存在性能不佳的附件时的附件序列()
*系统realloc()。
*其生长模式为:0,4,8,16,25,35,46,58,72,88。。。
*/
新分配=(新闻大小>>3)+(新闻大小<9?3:6);
请参阅(Python 2.7版本)


当然,实际的
len()
输出确实反映了列表引用的项数。

列表对象不会在每次删除时调整内部C数组的大小;那将是非常低效的

相反,在添加元素时,list对象会根据需要定期过度分配新内存,而在删除时,仅当删除的内存足以容纳已分配空间的一半时,才会调整其大小。从C代码:

if(已分配>=newsize&&newsize>=(已分配>>1)){
断言(self->ob_item!=NULL | | newsize==0);
Py_大小(自身)=新闻大小;
返回0;
}
其中,
newsize
是存储的对象引用的实际计数,
allocated
是过度分配的列表对象的大小。当
newsize
仍大于或等于所分配空间的一半时,上述测试将跳过重新分配

即使在缩小列表时,数组仍会被分配过多以接收新元素;列表数组中始终至少有3个插槽为空

因此,
sys.getsizeof()
在删除足够的元素之前保持稳定:

>>> from sys import getsizeof
>>> x = [1, 2, 3, 4] * 3
>>> x
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> print getsizeof(x), x
168 [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> print getsizeof(x), x
168 [1, 2, 3, 4, 1, 2, 3, 4]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> del x[-1]
>>> print getsizeof(x), x
136 [1, 2, 3, 4]
在另一个方向上,添加元素时,“列表过度分配”会使列表按与存储的引用数成比例的步长增长:

/*这与列表大小成比例的超额分配,腾出空间
*为了进一步的增长。这种过度分配是温和的,但也很严重
*足以在长期内产生线性时间摊销行为
*存在性能不佳的附件时的附件序列()
*系统realloc()。
*其生长模式为:0,4,8,16,25,35,46,58,72,88。。。
*/
新分配=(新闻大小>>3)+(新闻大小<9?3:6);
请参阅(Python 2.7版本)

当然,实际的
len()