Python列表的大小能有多大?

151
在Python中,列表的大小有多大?我需要一个大约包含12000个元素的列表。我仍然能够运行列表方法(如排序等)吗?
10个回答

235
根据源代码,列表的最大大小为PY_SSIZE_T_MAX/sizeof(PyObject*)PY_SSIZE_T_MAXpyport.h中定义为((size_t) -1)>>1
在普通的32位系统上,这是(4294967295 / 2)/ 4或536870912。
因此,在32位系统上,Python列表的最大大小为536,870,912个元素。
只要您拥有的元素数量等于或低于此数量,所有列表函数都应正确操作。

5
为什么 sizeof(PyObject*) == 4?这代表什么意思? - Matt
4
@Matt,是一个 PyObject * 所占用的字节数。这个东西是所谓的指针(你可以通过结尾的星号来认识它们)。指针长为 4 字节,并存储指向分配对象的内存地址。它们长度“仅”为 4 字节,因为现今计算机的 4 字节足以寻址内存中的每个元素。 - Antonio Ragagnin
1
值得注意的是(正如Álvaro Justen的回答所示),在其他机器上,特别是运行64位系统的机器上,PY_SSIZE_T_MAX的值可能会有很大的差异。 - ClydeTheGhost
1
@ClydeTheGhost,能否说明64位系统运行时最大元素数是否也可以比536,870,912更小呢?还是它们可能会变化很大,但最大尺寸总是等于或大于 536,870,912 元素? - a.t.
1
@a.t. 64位系统的最大值始终不小于32位系统的最大值。 - ClydeTheGhost
32位系统是(2^31-1)/4,而64位系统是(2^63-1)/8。(32位约为5亿,64位约为万亿) - thorr18

108

正如Python文档所述

sys.maxsize

平台支持的Py_ssize_t类型能表示的最大正整数,也就是列表、字符串、字典和许多其他容器的最大尺寸。

在我的电脑上(Linux x86_64):

>>> import sys
>>> print sys.maxsize
9223372036854775807

15
sys.maxsize是问题的答案。不同的架构支持不同的最大值。 - Simon Kuang
3
9223372036854775807个元素?真的吗?这与最受赞同的答案非常不同。 - akki
15
被接受的答案是针对32位系统的。因为现在已经是2016年,我会假设你正在使用64位系统,因此该答案是正确的。 - Brian Leach
5
应选此答案。 - Lokesh
6
在32位平台上,Sys.maxsize应该为2^31 - 1,在64位平台上应该为2^63 - 1(分别为2147483647或9223372036854775807)。然而,由于在32位系统中每个指针占用4个字节,在64位系统中为8个字节,因此如果您试图在64位系统上创建大于maxsize/8的列表或在32位系统上创建大于maxsize/4的列表,Python将会报错。 - thorr18
显示剩余2条评论

30

没问题。实际上,您可以轻松地自己看到:

l = range(12000)
l = sorted(l, reverse=True)

在我的机器上运行这些代码所花费的时间为:

real    0m0.036s
user    0m0.024s
sys  0m0.004s

但正如其他人所说,数组越大,操作速度越慢。


21
这种方式计时可能会误导——大部分时间都用在启动Python解释器上了。更好的方法是:python -m timeit.py "l=range(12000); l=sorted(l, reverse=True)"。在我的机器上,这个示例的时间大约缩短了1/20。 - dF.
5
@dF,你提到的准确性是正确的。感谢你指出这一点。我只是想证明一个观点。而这个例子证明了这一点。 - Nadia Alramli
14
@dF:太棒了!0.024秒对我来说实在是太长了,我很高兴现在不用再担心这个了。 - Thomas Edleson

7

在非正式的代码中,我创建了包含数百万元素的列表。我相信Python的列表实现仅受系统内存量的限制。

此外,列表方法/函数应该继续适用于列表的大小,无论大小如何。

如果您关心性能,可能值得研究诸如NumPy之类的库。


5

在Python中,12000个元素并不算什么...实际上,元素的数量可以一直增加,直到Python解释器在您的系统上耗尽内存为止。


5

Effbot上介绍了列表的性能特征

Python列表实际上被实现为向量,以便进行快速随机访问,因此容器将基本上保存与内存中空间相同数量的项(需要用于列表中包含的指针的空间以及指向的对象在内存中占用的空间)。

添加操作的时间复杂度是O(1)(平均常数复杂度),但在序列中插入或删除元素需要进行O(n)(线性复杂度)重排序,并且随着列表中元素数量的增加,重排序所需的时间会越来越长。

关于排序问题更加微妙,由于比较操作可能需要不受限制的时间,如果执行非常缓慢的比较操作,则可能需要很长时间,尽管这不是Python列表数据类型的问题。

反转只需要交换列表中所有指针所需的时间(必须是O(n)(线性复杂度),因为您每次都要触摸每个指针)。


5

不同系统的最大内存限制是不同的。最简单的方法是

import six six.MAXSIZE 9223372036854775807 此代码可以给出listdict的最大大小,具体请参见文档


2
这不是文档。 - user3064538
使用 sys 而非 six 是正确的。 - Reza K Ghazi

1
我认为你只受可用RAM总量的限制。显然,数组越大,对其进行操作所需的时间就越长。

5
一般来说是正确的,但并非所有情况都如此--追加仍然是摊销常数时间,与数组的大小无关。 - cdleary

1
我从一个x64位系统中得到了这个: Python 3.7.0b5 (v3.7.0b5:abb8802389, May 31 2018, 01:54:01) [MSC v.1913 64 bit (AMD64)] on win32

enter image description here


6
如果您能再详细阐述一些细节,并说明他人如何找到自己的极限,那么这将是一个很好的答案。 - shayaan

-19

列表数量没有限制。 导致错误的主要原因是RAM。 请升级您的内存大小。


14
-1是因为它实际上没有回答问题,并且实际上具有误导性,因为(正如其他答案所示),列表确实有最大大小限制。 - ClydeTheGhost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接