5

我正在做一件愚蠢的事情,例如:

from itertools import *
rows = combinations(range(0, 1140), 17)
all_rows = []
for row in rows:
    all_rows.append(row)

没有惊喜; 我用完了内存地址空间(32 位 python 3.1) 我的问题是:我如何计算一个大列表需要多少内存地址空间?在这种情况下,列表的顺序为2.3X10^37。Python中是否有一个函数可以返回我正在寻找的信息,或者实际上是一个较小但相似的列表的大小?那些工具是什么?

4

4 回答 4

11

有一个方便的函数sys.getsizeof()(从 Python 2.6 开始)可以帮助解决这个问题:

>>> import sys
>>> sys.getsizeof(1)  # integer
12
>>> sys.getsizeof([]) # empty list
36
>>> sys.getsizeof(()) # empty tuple
28
>>> sys.getsizeof((1,))  # tuple with one element
32

从中可以看出,每个整数占用 12 个字节,列表或元组中每个引用的内存为 4 个字节(在 32 位机器上)加上开销(分别为 36 或 28 个字节)。

如果您的结果有长度为 17 的整数元组,那么17*(12+4)+28每个元组将有 300 个字节。结果本身是一个列表,因此 36 个字节加上每个引用 4 个字节。找出列表的长度(称为 N)以及36+N*(4+300)所需的总字节数。

编辑:还有另一件事可能会显着影响该结果。Python 根据需要为大多数整数值创建新的整数对象,但对于较小的整数对象(根据经验确定为 Windows 上 Python 2.6.4 上的范围 [-5, 256]),它会预先创建它们并重新使用它们。如果您的大部分值小于 257,这将显着减少内存消耗。(在 Python 上257 is not 257+0;-))。

于 2009-12-31T16:35:36.157 回答
4

好吧,首先而不是写:

all_rows = []
for row in rows:
    all_rows.append(row)

你可以简单地写:

all_rows = list(rows)

这将更有效率。

然后,列表的内存消耗需要考虑两件事:

  • 构成列表的对象的内存消耗;这显然取决于这些对象、它们的类型以及是否有很多共享
  • 列表本身的内存消耗;列表中的每个对象都由一个指针引用,该指针在 32 位模式下占 4 个字节,在 64 位模式下占 8 个字节;所以,粗略地说,列表本身的大小是(4 或 8 个字节)乘以列表中的对象数量(这忽略了固定的列表头开销和 Python 列表所做的适度的过度分配)

顺便说一句,在最近的 Python 版本中,您可以使用它sys.getsizeof()来获取对象的大小:

>>> import sys
>>> sys.getsizeof([None] * 100)
872
于 2009-12-31T16:29:47.767 回答
3

附录:由于您正在处理整数列表并担心内存使用——还有array-module:

[ array] 定义了一个对象类型,它可以紧凑地表示一组基本值:字符、整数、浮点数。数组是序列类型,其行为与列表非常相似,只是其中存储的对象类型受到限制。类型在对象创建时指定 [...]。

于 2009-12-31T16:47:54.610 回答
1

你要求

http://en.wikipedia.org/wiki/Binomial_coefficient

http://www.brpreiss.com/books/opus7/programs/pgm14_10.txt

无论如何,听起来你正试图通过蛮力解决一个 NP 完全问题;)

于 2009-12-31T16:26:26.963 回答