2015-03-22 6 views

ответ

5

Да, есть предел того, сколько элементов списка Python может содержать, см sys.maxsize. Однако вы его не ударили; очень мало машин имеют достаточно памяти, чтобы удержать это много предметов.

Вы пытаетесь создать список с 1073741824 ссылками; каждая ссылка также занимает память. Это зависит от вашей ОС, сколько, но обычно это будет 4 байта для 32-битной системы, 8 байт для 64-битной ОС, где 2^30 элементов будут занимать 4 ГБ или 8 ГБ памяти, только для список ссылок.

4GB плюс другие элементы уже легко больше, чем большинство современных операционных систем позволяют использовать один процесс в памяти.

На моем Mac OS X машины (с использованием 64-битной ОС), sys.maxsize равно 2^63, а также ссылки на объекты Python в списке займет 8 байт:

>>> import sys 
>>> sys.maxsize 
9223372036854775807 
>>> sys.maxsize.bit_length() 
63 
>>> sys.getsizeof([]) # empty list overhead 
72 
>>> sys.getsizeof([None]) - sys.getsizeof([]) # size of one reference 
8 

Таким образом, чтобы создать список с sys.maxsize элементов вам понадобится 64 exbibytes памяти, только для справки. Это больше, чем адрес 64-разрядного компьютера (practical maximum is about 16 exbibytes).

Все это игнорирует объем памяти, который будут иметь объекты, на которые вы ссылаетесь в списке. None - синглтон, поэтому он будет фиксировать только фиксированный объем памяти. Но предположительно вы собирались хранить что-то еще в этом списке, и в этом случае вам тоже нужно учитывать это.

И вообще говоря, вы никогда не должны нуждаетесь в, чтобы создать такой большой список. Используйте разные методы; создайте разреженную структуру, используя словарь, например, я сомневаюсь, что вы планируете обращаться ко всем этим 2^30 индексам непосредственно в свой алгоритм.

0

Вы пытаетесь создать огромный список здесь, и у вас недостаточно свободной памяти для этого. Сколько оперативной памяти вам понадобится?

Это будет примерно 8Gb на моей машине. Вы можете найти размер None на вашей машине:

import sys 
sys.getsizeof(None) # 16 here 

Но для списка вы можете приблизить это следующим образом:

sys.getsizeof([None] * (2**20)) # 8388680 

и надеясь, что для 2**30 это займет примерно 2**10 раза больше вы будете в конечном итоге с 8388680 * 2**10, который составляет приблизительно 8 ГБ.

+1

'None' - это одноэлементный, только один будет * один * такой объект, берущий эти 16 байт. Вы можете создать столько ссылок на него, сколько хотите, это * ссылки *, которые берут память. Ссылка на 64-разрядную машину обычно составляет 8 байтов, в зависимости от ОС. –

+0

Не знал этого. Спасибо, что указал на проблему. Обновлен ответ. –

Смежные вопросы