Firstly, sys.getsizeof()
returns bytes, not bits. So you would be looking for 3. However, that's not possible, since all Python objects have overhead. As well, lists doesn't actually contain their elements, but pointers to them. Then I'm sure there are a lot of implementation details that further complicate things, but I'm not really qualified to talk about them.
That said, you can get closer with array
, which actually does contain its elements.
import array
import sys
L = [1, 2, 3]
print(sys.getsizeof(L)) # -> 80
a = array.array('B', L) # "B" stands for "byte", AKA "unsigned char" in C
print(sys.getsizeof(a)) # -> 67
At this scale, the difference is marginal, but with as little as 256 elements, it's an order of magnitude.
L = list(range(0x100))
print(sys.getsizeof(L)) # -> 2104
a = array.array('B', L)
print(sys.getsizeof(a)) # -> 320
For more advanced uses, look into NumPy's ndarray
.
import numpy as np
nda = np.array(L, dtype='uint8')
print(sys.getsizeof(nda)) # -> 352
You could also consider using a bytearray
, though semantically it makes less sense since you're trying to store numbers as bytes, not the bytes themselves. Look at the repr below to see what I mean.
ba = bytearray(L)
print(sys.getsizeof(ba)) # -> 342
print(ba[:11]) # -> bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n')