
As long as you are a Python developer, you must have used the List. It is the most commonly used container type in Python. Also, I guess you must know that we can use the paired square brackets []
to initialise an empty list.
This article actually starts with a discussion with someone. He argued that using list()
to initialise a Python List is more readable. Apparently, this guy is likely coming from other Programming languages. Well, I said that it is indeed not the end of the world if someone insists to write something like my_list = list()
. But frankly speaking, my_list = []
is not only more "Pythonic", but it is also even faster.
In this article, I’ll demonstrate the comparison of the performance. More importantly, I’ll show you why my_list = []
is faster.
A Comparison of Performance

Before diving into the details, it is always better to verify the performance. It is always recommended to prove the idea before protecting it and even arguing
Let’s start with the two ways of initialising Python lists.
my_list_1 = []
my_list_2 = list()

In terms of the outcome, they are identical. Both of the two statements give us a Python List. Now, we need to measure the performance.
With Python notebooks such as Jupyter, it is very easy to measure the performance using the magic command %timeit
.
%timeit my_list_1 = []
%timeit my_list_1 = list()
Please note that the two lines of code above need to be run in different cells.

As shown in the results, using []
is roughly 3 times faster than list()
. It is very confident because the results are based on 10,000,000 runs.
You might also interesting in some other similar scenarios such as {}
and dict()
. In fact, the performance gap exists in these cases as well.

A Breakdown Investigation with Bytecode

To understand what happened behind the scene, we can go to the lower level of Python to find the answer, which is the bytecode.
Bytecode can be thought of as a series of instructions or a low-level program for the Python interpreter. It is not necessary to learn it for most developers, but it is good to know such a thing existing. This time, we will use the bytecode to investigate what happened during the two List initialisation statements are running.
There is a built-in module in Python called dis
(stands for "Disassembler") that can disassemble a Python code into bytecode.
from dis import dis
dis("[]")
dis("list()")

We can see that the bytecodes of the two methods are completely different. That must be the reason why the performance is different.
When we use []
, the bytecode shows that there are only two steps.
BUILD_LIST
– Quite self-explained, just build a Python ListRETURN_VALUE
– Return the value
Very simple, right? When the Python interpreter sees the expression []
it just knows that it needs to build a list. So, it is very straightfoward.
How about list()
?
LOAD_NAME
– Try to find the object "list"CALL_FUNCTION
– Call the "list" function to build the Python ListRETURN_VALUE
– Return the value
Every time we use something with a name, the Python interpreter will search the name in the existing variables. The order is Local Scope -> Enclosing Scope -> Global Scope -> Built-in Scope (I will not expand this topic in this article. Please let me know if you are interested in this. I will write another article about it).
This search will definitely need some time. Have you ever tried to use some variables or functions that have not been defined? For example, if we had a typo of a variable or function name, a NameError
will be thrown as follows.

This is the case that the Python interpreter has tried to look for the name in all the scopes but didn’t find any matches.
list
is in the built-in scope so that the interpreter can definitely find it. Then, the interpreter realises that we have put a pair of parentheses ()
after it, so it is a function that should be called.
Finally, the list will be built and returned.
A Discussion of Literal Constants

Alright, we have known that list()
needs extra steps to search the function name and call it, but why the interpreter knows what []
should do?
The key is called "Literal Constant" or "Literal Value".
The most common literal constant will be numbers and strings, such as 23
and 'hello'
. When we write such expressions, the interpreter knows that they are literal values. So, they don’t need to match anything in any variable scopes.

The expressions []
and {}
are also literal values in Python.
Summary

In this article, I have demonstrated that using []
and list()
to initialise a Python List is completely different, both in terms of the performance and the actual steps behind the scene.
This is probably taking unnecessary pains to study such an insignificant problem. However, splitting hairs sometimes enable us to find some more knowledge that might help in other ways.
Read every story from Christopher Tao (and thousands of other writers on Medium)
If you feel my articles are helpful, please consider joining Medium Membership to support me and thousands of other writers! (Click the above link)