Here's a more complete interactive session that will help me explain what is happening (Python 2.6 on 32-bit Windows XP, but that doesn't matter):
>>> import sys >>> sys.getsizeof([]) 36 >>> sys.getsizeof([1]) 40 >>> lst = [] >>> lst.append(1) >>> sys.getsizeof(lst) 52 >>>
Note that the empty list is slightly smaller than the one with [1] . However, when an element is added, it becomes much larger.
The reason for this is the implementation details in Objects/listobject.c , in the CPython source.
Empty list
When an empty list [] , space for elements is not allocated - this can be seen in PyList_New . 36 bytes is the amount of space needed for the list data structure itself on a 32-bit machine.
Single item list
When creating a list with one element [1] , space for one element is allocated in addition to the memory required by the list structure itself. Again, this can be found in PyList_New . Given size as an argument, it computes:
nbytes = size * sizeof(PyObject *);
And then has:
if (size <= 0) op->ob_item = NULL; else { op->ob_item = (PyObject **) PyMem_MALLOC(nbytes); if (op->ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory(); } memset(op->ob_item, 0, nbytes); } Py_SIZE(op) = size; op->allocated = size;
So, we see that with size = 1 space is allocated for one pointer. 4 bytes (in my 32-bit field).
Add to an empty list
When calling append on an empty list, this is what happens:
PyList_Append calls app1app1 asks for the size of the list (and gets 0 as an answer)app1 then calls list_resize with size+1 (1 in our case)list_resize has an interesting distribution strategy summarized in this comment from its source.
There he is:
new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); if (new_allocated > PY_SIZE_MAX - newsize) { PyErr_NoMemory(); return -1; } else { new_allocated += newsize; }
Let's do some math
Let's see how the numbers that I quoted in the session at the beginning of my article are achieved.
Thus, 36 bytes is the size required by the list data structure itself on a 32-bit basis. With one element, space is allocated for one pointer, so 4 extra bytes are a total of 40 bytes. OK so far.
When app1 is called on an empty list, it calls list_resize with size=1 . According to the list_resize redistribution list_resize , the next largest available size after 1 is 4, so 4 pointers will be highlighted. 4 * 4 = 16 bytes and 36 + 16 = 52.
In fact, everything makes sense :-)