Please explain how python decides on the size or capacity of lists, when they're created (with list(), using list comprehension ...),and when they're modified.
I have these questions because i tried the following little program and got a bit confused and curious by the results. (Maybe my formulas are wrong!)
from sys import getsizeof
empty_list = []
list_base_size = getsizeof(empty_list)
print(f"{list_base_size = } bytes.")
print()
list_manually = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
]
list_manually_size = getsizeof(list_manually)
list_manually_capacity = (list_manually_size - list_base_size) // 8
print(f"{list_manually_size = } bytes.")
print(f"{list_manually_capacity = } elemnts.")
print()
list_constructor = list(range(20))
list_constructor_size = getsizeof(list_constructor)
list_constructor_capacity = (list_constructor_size - list_base_size) // 8
# list capacity should also be equal to :
# from cpython
# new_allocated = (size_t)newsize (newsize >> 3) (newsize < 9 ? 3 : 6);
print(f"{list_constructor_size = } bytes.")
print(f"{list_constructor_capacity = } elemnts.")
print()
list_comprehension = [i for i in range(20)]
list_comprehension_size = getsizeof(list_comprehension)
list_comprehension_capacity = (list_comprehension_size - list_base_size) // 8
print(f"{list_comprehension_size = } bytes.")
print(f"{list_comprehension_capacity = } elemnts.")
Output
ist_base_size = 56 bytes.
list_manually_size = 216 bytes.
list_manually_capacity = 20 elemnts.
list_constructor_size = 216 bytes.
list_constructor_capacity = 20 elemnts.
list_comprehension_size = 248 bytes.
list_comprehension_capacity = 24 elemnts.
CodePudding user response:
When you create a list from anything whose length is known (i.e. you can call len
on it) the list will be initialized to the exact correct size. A comprehension size isn't known so the list grows in capacity every time the existing capacity gets filled. It grows by more than 1 to be efficient.