Python 如何限制用于存储整数的内存量?

Python 如何限制用于存储整数的内存量?,python,python-3.x,memory,integer,byte,Python,Python 3.x,Memory,Integer,Byte,当我调用sys.getsizeof(4)时,它返回14。假设这与C中的sizeof()相同,那么这个值就高得令人无法接受 我想使用内存数组作为一个大的原始字节数组。由于项目中阵列的大小,内存开销是最重要的。可移植性也是一个巨大的问题,因此使用C语言或使用更奇特的库并不是最理想的 有没有一种方法可以迫使Python只使用标准的Python3来减少单个带正号的字节列表或元组成员的内存?14考虑到Python对象必须至少具有 PyObject 所有对象类型都是此类型的扩展。这是一种包含Python将指

当我调用sys.getsizeof(4)时,它返回
14
。假设这与C中的
sizeof()
相同,那么这个值就高得令人无法接受

我想使用内存数组作为一个大的原始字节数组。由于项目中阵列的大小,内存开销是最重要的。可移植性也是一个巨大的问题,因此使用C语言或使用更奇特的库并不是最理想的


有没有一种方法可以迫使Python只使用标准的Python3来减少单个带正号的字节列表或元组成员的内存?

14考虑到Python对象必须至少具有

PyObject

所有对象类型都是此类型的扩展。这是一种包含Python将指向对象的指针视为对象所需信息的类型。在正常的“release”构建中,它只包含对象的引用计数和指向相应类型对象的指针。实际上没有任何东西被声明为PyObject,但指向Python对象的每个指针都可以转换为PyObject*。必须使用宏Py_REFCNT和Py_TYPE来访问成员

对于每个Python对象,您都会有这样的开销。降低开销/有效负载比率的唯一方法是拥有更多的有效负载,例如在数组中(普通Python和numpy)

这里的诀窍是数组元素通常不是Python对象,因此它们可以省去refcount和type指针,并占用与底层C类型一样多的内存。

(帽子尖到martineau

如果您只关心无符号字节(值[0255]),那么最简单的答案可能是内置的及其不可变的同级。 一个潜在的问题是,它们用于表示编码字符串(从外部世界读取或写入),因此它们的默认值
\uuuuu repr\uuuu
是“类似字符串”,而不是整数列表:

>>> lst = [0x10, 0x20, 0x30, 0x41, 0x61, 0x7f, 0x80, 0xff]
>>> bytearray(lst)
bytearray(b'\x10 0Aa\x7f\x80\xff')
>>> bytes(lst)
b'\x10 0Aa\x7f\x80\xff'
请注意,空格、
'0'
'A'
'A'
按字面意思显示,而“不可打印”值显示为
'\x##'
字符串转义序列。 如果你想把这些字节看成一堆整数,这不是你想要的

对于固定宽度整数或浮点数的齐次数组(非常类似于C),请使用标准库的

导入数组 #1兆字节的无符号8位整数。 >>>a=array.array('B',(n%2**8表示范围(2**20)中的n) >>>len(a) 1048576 >>>a.类型码 “B” >>>a.项目规模 1. >>>a.缓冲区信息()#内存地址、内存大小。 (24936384, 1048576) >>>a_slice=a[slice(10241040)]#可以像列表一样进行切片。 >>>一片 数组('B',[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) >>>type(a_slice)#slice也是一个数组,而不是列表。 对于更复杂的数据,最常用的方法是打包异构记录,很像C的
struct
关键字。 与C不同,我看不到任何明显的方法来创建
struct
s的
array

这些数据结构都使用Python,Python(至少在CPython中)允许Python类将其内部类似C的数组直接暴露给其他Python代码。 如果你需要做一些复杂的事情,你可能需要学习这个。。。
或者放弃并使用。

如果您能够使用库,则提供优化的数组以及操作它们的有效函数。您可以使用数组的dtype参数指定元素的内存大小。尝试使用带有合适类型代码的
array.array()
。跟进marineau的评论:标准库的一部分的文档。太棒了,array.array()正是我要找的,谢谢martineau和Kevin!如果可能的话,我试着避免使用numpy,numpy很好,只是不确定它在这种情况下是否有效。
>>> import array

# One megabyte of unsigned 8-bit integers.
>>> a = array.array('B', (n % 2**8 for n in range(2**20)))
>>> len(a)
1048576
>>> a.typecode
'B'
>>> a.itemsize
1
>>> a.buffer_info()  # Memory address, memory size.
(24936384, 1048576)

>>> a_slice = a[slice(1024, 1040)]  # Can be sliced like a list.
>>> a_slice
array('B', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
>>> type(a_slice)  # Slice is also an array, not a list.
<class 'array.array'>