Why do two identical lists have a different memory footprint?

I created two lists l1 and l2, but each one with a different creation method:

    import sys

    l1 = [None] * 10
    l2 = [None for _ in range(10)]

    print('Size of l1 =', sys.getsizeof(l1))
    print('Size of l2 =', sys.getsizeof(l2))

But the output surprised me:

    Size of l1 = 144
    Size of l2 = 192

The list created with a list comprehension is a bigger size in memory, but the two lists are identical in Python otherwise.

Why is that? Is this some CPython internal thing, or some other explanation?

When you write [None] * 10, Python knows that it will need a list of exactly 10 objects, so it allocates exactly that.

When you use a list comprehension, Python doesn't know how much it will need. So it gradually grows the list as elements are added. For each reallocation it allocates more room than is immediately needed, so that it doesn't have to reallocate for each element. The resulting list is likely to be somewhat bigger than needed.

You can see this behavior when comparing lists created with similar sizes:

    >>> sys.getsizeof([None]*15)
    184
    >>> sys.getsizeof([None]*16)
    192
    >>> sys.getsizeof([None for _ in range(15)])
    192
    >>> sys.getsizeof([None for _ in range(16)])
    192
    >>> sys.getsizeof([None for _ in range(17)])
    264

You can see that the first method allocates just what is needed, while the second one grows periodically. In this example, it allocates enough for 16 elements, and had to reallocate when reaching the 17th.

From: stackoverflow.com/q/51526242

Back to homepage or read more recommendations: