Каковы требования к памяти для большого списка Python?

Я делал глупость как:

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, который возвращает информацию, которую я ищу, или на самом деле размер меньшего, но подобного списка? Каковы те инструменты?

5
задан Nathaniel Ford 19 August 2019 в 17:39
поделиться

4 ответа

Есть удобная функция 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 ;-)).

11
ответ дан 18 December 2019 в 08:28
поделиться

Вы просите

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

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

Как бы то ни было, звучит так, будто вы пытаетесь решить проблему NP-завершения грубой силой ;)

1
ответ дан 18 December 2019 в 08:28
поделиться

Дополнение: поскольку вы имеете дело со списками целых чисел и беспокоитесь об использовании памяти --- существует также array -module:

[ array ] определяет тип объекта, который может компактно представлять массив основных значений: символы, целые числа, числа с плавающей запятой. Массивы являются последовательными типами и ведут себя очень похоже на списки, за исключением того, что тип хранимых в них объектов ограничен. Тип указывается при создании объекта [...].

3
ответ дан 18 December 2019 в 08:28
поделиться

, в первую очередь, а не написание:

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

Вы можете просто написать:

all_rows = list(rows)

, который будет довольно более эффективным.

Тогда есть два веща, которые следует учитывать для рассмотрения памяти списка:

  • расход памяти объектов, содержащих список; Это, очевидно, зависит от этих объектов, их типа, и есть ли много совместного использования или нет
  • расхода памяти самого списка; Каждый объект в списке ссылается указатель, который примет 4 байта в 32-битном режиме и 8 байта в 64-битном режиме; Таким образом, примерно, размер самого списка (4 или 8 байтов) раз больше объектов в списке (это игнорирует надерну заголовка фиксированного списка и умеренное количество чрезмерного распределения, которые списки Python делают)

Путь в недавних версиях Python вы можете использовать Sys.getsizeof () , чтобы получить размер объекта:

>>> import sys
>>> sys.getsizeof([None] * 100)
872
4
ответ дан 18 December 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: