0
List = [1,2,3]
print(sys.getsizeof(List))

Output : 96

That's a lot of space!!!

I am working on a problem-solving program and my only requirement is having a list that will store multiple int whose value will be 0 to 100.

As per my knowledge, this range's int can be stored by 8 bit. So total size would be len(list) * 8

So, in python is this possible to do something like this?

  • no, at least not to my knowledge – feverdreme Jan 20 '21 at 17:22
  • Does this answer your question? [Size of list in memory](https://stackoverflow.com/questions/7247298/size-of-list-in-memory) – couka Jan 20 '21 at 17:24
  • Use `numpy`, it allows you to choose a byte type and minimizes the overhead. – Mark Ransom Jan 20 '21 at 17:26
  • 2
    The size of a list has ABSOLUTELY NOTHING to do with the size of the elements of the list - all it actually stores is references to the elements, which will be a 32- or 64-bit pointer depending on your platform's bit size. – jasonharper Jan 20 '21 at 17:58
  • 1
    Python != C. *everything* is an object. Variables reference objects, and don't have a size. – juanpa.arrivillaga Jan 20 '21 at 18:25
  • @jasonharper Yeah, but my question was about decreasing each `int` size in the list not size of reference pointer to that list. – stack aayush Jan 21 '21 at 12:55

1 Answers1

2

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')
wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • Does that have an advantage over `bytearray`? – superb rain Jan 20 '21 at 17:40
  • 1
    @superb Well, I guess semantically it makes more sense. We're storing numbers as bytes, not the bytes themselves. As well, `bytearray` doesn't support signed ints, which I'm using here, although that's not really important or relevant to the question. – wjandrea Jan 20 '21 at 18:07