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

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

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

просто предупреждаю: C++ короткий, а не 2 байта шириной. Это зависит от реализации.

user3063349 23.06.2017 18:52

Если вы выполняете какие-либо манипуляции с этим огромным набором данных, вы, вероятно, захотите использовать Numpy, который поддерживает широкий спектр числовых типов и эффективные операции с их массивами.

giltay 23.09.2008 17:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
24
2
43 483
6

Ответы 6

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

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

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

Лучший и более полный ответ, чем мой собственный. :)

Nick Johnson 23.09.2008 14:45

Итак, является ли массив ('h') только с одним элементом тем же, что и создание короткого целого числа?

Arnav 23.09.2008 14:50

@Arnav: нет. это будет PyObject + короткое целое число.

Armin Ronacher 23.09.2008 15:33

Спасибо Армину за указание на модуль «массив». Я также нашел модуль '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

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

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

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

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

Могу ли я использовать IIBTree без установки всего Zope? Где мне это достать? Что такое IOBTree?

Greg 23.09.2008 20:48

Просто установите ZODB (pypi.python.org/pypi/ZODB3/3.8.0). IOBTree - это дерево BT, которое имеет целочисленные ключи (I) и значения объектов (O).

Tony Meyer 27.09.2008 01:30

Вы также можете хранить несколько целых чисел любого размера в одном большом целом числе.

Например, как показано ниже, в python3 в 64-битной системе x86 1024 бита занимают 164 байта памяти. Это означает, что в среднем один байт может хранить около 6,24 бита. А если вы выберете еще большие целые числа, вы сможете получить еще более высокую плотность хранения битов. Например, около 7,50 бит на байт с целым числом 2 ** 20 бит.

Очевидно, вам понадобится некоторая логика оболочки для доступа к отдельным коротким числам, хранящимся в большем целом числе, что легко реализовать.

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

Если вы одновременно обращаетесь к большому пакету последовательно сохраненных целых чисел, чтобы минимизировать доступ к большим целым числам, то более медленный доступ к длинным целым числам не будет проблемой.

Я думаю, что использование numpy будет более простым подходом.

>>> a = 2**1024
>>> sys.getsizeof(a)
164
>>> 1024/164
6.2439024390243905

>>> a = 2**(2**20)
>>> sys.getsizeof(a)
139836
>>> 2**20 / 139836
7.49861266054521

Использование bytearray в python, который в основном представляет собой массив C unsigned char под капотом, будет лучшим решением, чем использование больших целых чисел. Нет накладных расходов на манипулирование байтовым массивом, и у него гораздо меньше накладных расходов на хранилище по сравнению с большими целыми числами. С байтовыми массивами можно получить плотность хранения 7,99+ бит на байт.

>>> import sys
>>> a = bytearray(2**32)
>>> sys.getsizeof(a)
4294967353
>>> 8 * 2**32 / 4294967353
7.999999893829228

Вы можете использовать int NumyPy как np.int8 или np.int16.

Другие вопросы по теме