Я делал глупость как:
from itertools import *
rows = combinations(range(0, 1140), 17)
all_rows = []
for row in rows:
all_rows.append(row)
Не удивительно; у меня заканчивается пространство адреса памяти (Python на 32 бита 3.1
) Мой вопрос: как я вычисляю, в каком количестве пространства адреса памяти я буду нуждаться для большого списка? В этом случае список находится на порядке 2.3X10^37
. Существует ли функция в Python, который возвращает информацию, которую я ищу, или на самом деле размер меньшего, но подобного списка? Каковы те инструменты?
Есть удобная функция 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 создает новые целочисленные объекты, как это требуется для большинства целочисленных значений, но для малых (эмпирически определенных как диапазон [-5, 256] на Python 2.6.4 на Windows) он предварительно создаёт их все и использует повторно. Если большая часть ваших значений меньше 257, то это значительно сократит потребление памяти. (На Python 257 не 257+0
;-)).
Вы просите
http://en.wikipedia.org/wiki/Binomial_coefficient
http://www.brpreiss.com/books/opus7/programs/pgm14_10.txt
Как бы то ни было, звучит так, будто вы пытаетесь решить проблему NP-завершения грубой силой ;)
Дополнение: поскольку вы имеете дело со списками целых чисел и беспокоитесь об использовании памяти --- существует также array
-module:
[
array
] определяет тип объекта, который может компактно представлять массив основных значений: символы, целые числа, числа с плавающей запятой. Массивы являются последовательными типами и ведут себя очень похоже на списки, за исключением того, что тип хранимых в них объектов ограничен. Тип указывается при создании объекта [...].
, в первую очередь, а не написание:
all_rows = []
for row in rows:
all_rows.append(row)
Вы можете просто написать:
all_rows = list(rows)
, который будет довольно более эффективным.
Тогда есть два веща, которые следует учитывать для рассмотрения памяти списка:
Путь в недавних версиях Python вы можете использовать Sys.getsizeof ()
, чтобы получить размер объекта:
>>> import sys
>>> sys.getsizeof([None] * 100)
872