Короткие целые числа в Python - PullRequest
       27

Короткие целые числа в Python

17 голосов
/ 23 сентября 2008

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

Итак, есть ли способ заставить Python использовать только 2 байта для некоторых целых чисел (эквивалент C ++ 'short')?

Ответы [ 3 ]

35 голосов
/ 23 сентября 2008

Неа. Но вы можете использовать короткие целые числа в массивах:

from array import array
a = array("h") # h = signed short, H = unsigned short

Пока значение остается в этом массиве, оно будет коротким целым числом.

5 голосов
/ 23 сентября 2008

Спасибо Armin за указание на модуль 'array'. Я также нашел модуль struct, который упаковывает структуры в стиле c в строку:

Из документации (https://docs.python.org/library/struct.html):

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('hhl')
8
2 голосов
/ 23 сентября 2008

Предложение Армина о модуле массива, вероятно, лучше. Два возможных варианта:

  • Вы можете создать модуль расширения самостоятельно, который обеспечивает структуру данных, к которой вы стремитесь. Если это действительно что-то вроде коллекции шорт, то это довольно просто сделать.
  • Вы можете обманывать и манипулировать битами, чтобы вы храните один номер в нижняя половина Python int, и еще один в верхней половине. Вы бы написали несколько служебных функций конвертировать в / из них в вашем структура данных. Ужасно, но это можно заставить работать.

Стоит также понимать, что целочисленный объект Python не 4 байта - это дополнительные издержки. Поэтому, если у вас действительно большое количество шорт, вы можете сэкономить более двух байтов на число, используя каким-либо образом короткую букву C (например, модуль массива).

Некоторое время назад мне приходилось хранить большой набор целых чисел в памяти, а словарь с целочисленными ключами и значениями был слишком велик (у меня было 1 ГБ для структуры данных IIRC). Я переключился на использование дерева IIBTree (от ZODB) и смог установить его. (Целые числа в дереве IIBTree - это настоящие целые числа C, а не целые числа Python, и я взломал автоматический переход на дерево IOBTree, когда число было больше 32 бит).

...