5
sys.getsizeof(list(range(10))) # 200
sys.getsizeof([0,1,2,3,4,5,6,7,8,9]) # 144
sys.getsizeof([i for i in range(10)]) # 192

I have very little C experience so this may be over my head, but I am curious as I am playing around with sys.getsizeof.

I tried to look at the documentation but I only found this:

getsizeof() calls the object’s sizeof method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

Due to my very little C experience I am not too familiar with GC as well but from my Python-related GC readings, I understand that only references are counted in Python. In the above situation, we aren't saving it to a variable so I am assuming no GC references?

glhr
  • 4,439
  • 1
  • 15
  • 26
Moondra
  • 4,399
  • 9
  • 46
  • 104
  • 3
    With the literal, Python knows exactly how much memory it needs to allocate for the resulting list. With the other two, the memory needed won't be known until the list constructor actually iterates over the `range` object. I'm not sure what the 8-byte difference between `list` and the list comprehension represents. – chepner Apr 12 '19 at 18:15
  • 2
    The dupe should clarify most of your objections. TL;DR: list's are a "growing" datastructure with some logic inside that tells it how much to overgrow to need reallocation on every insert. In some cases python can allocate the _exact_ size without need of iterativly enlarging the list which will lead to "not yet used but allocated" space to be reported by getsizeof – Patrick Artner Apr 12 '19 at 18:37

1 Answers1

6

It appears that python allocates some additional memory when using the list() and range() functions. If you copy the values from the generated arrays to a new array using [:] you can see that they become equal.

Example:

import sys

sys.getsizeof(list(range(10))[:]) # 144
sys.getsizeof([0,1,2,3,4,5,6,7,8,9][:]) # 144
sys.getsizeof([i for i in range(10)][:]) # 144
DobromirM
  • 2,017
  • 2
  • 20
  • 29