To get a new list from a list with an additional value, I used to think that list_b = [*list_a, value]
is more performant than list_b = list_a + [value]
, as the latter generates an intermediate [value]
.
However, according to the benchmark (tested in Python 3.12.3 / Windows 10), it seems that the result is opposite:
from timeit import timeit
import random
import matplotlib.pyplot as plt
num_data_points = 1000
step = 10
methods = [
# ordered from slowest to fastest to make the key easier to read
# "list_b = list_a.copy(); list_b += (value,)",
# "list_b = list_a.copy(); list_b.append(value)",
# "list_b = list(list_a); list_b.append(value)",
"list_b = [*list_a, value]",
"list_b = list_a + [value]",
]
x = list(range(0, num_data_points * step, step))
y = [[] for _ in methods]
for i in x:
list_a = list(range(i))
random.shuffle(list_a)
value = random.randint(0, num_data_points * step)
setup = f"list_a = {list_a}; value = {value}"
for method_index, method in enumerate(methods):
y[method_index].append(timeit(method, setup=setup, number=800))
print(i, "out of", num_data_points * step)
ax = plt.axes()
for method_index, method in enumerate(methods):
ax.plot(x, y[method_index], label=method)
ax.set(xlabel="size of the list", ylabel="time (s) (lower is better)")
ax.legend()
ax.figure.canvas.get_default_filetype = lambda: 'svg'
plt.show()
Can someone help explain why?
6
The difference is very minimal as far as I can see. I think this is Happening due to the use of *. From another use case I recall, it adds a small overhead as it iterates over a list.