Why is [ ] faster than list( ) in python?

Alex Barros
3 min readDec 5, 2021

--

Which one do you prefer to create lists in Python? You will be surprised to know they don't work exactly the same.

First of all, we will compare the performance of creating a list using the brackets directly versus using list() constructor.

Lets compare the time to create an empty list. We use the magic command %timeit , this executes the setup statement once, and then returns the time it takes to execute the main statement a number of times, measured in seconds as a float. The argument is the number of times through the loop, defaulting to one million.

Comparison between [] and list()

To create an empty list, [] runs more than three times faster than list(), and if I am creating a list with some content?

Creating list with some content

Because []is a literal syntax. Python can create bytecode just to create the list. We will use the dis module. It supports the analysis of CPython bytecode by disassembling it.

As we can see at the picture above, the name list() is a separed variable and need to be resolved, the stack has to be involved to push the arguments, the frame has to be stored to retrieve later, and a call has to be made. That all takes more time.

For the empty case, that means you have at the very least a LOAD_NAME (which has to search through the global namespace as well as the builtins module) followed by a CALL_FUNCTION, which has to preserve the current frame.

The case with numerical content, the disasembler is pretty similar:

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.

  1. BUILD_LIST — Build a Python List
  2. RETURN_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()?

  1. LOAD_NAME — Try to find the object “list” into all scope variables
  2. CALL_FUNCTION — Call the “list” function to build the Python List
  3. RETURN_VALUE — Return the value

Every time we use something with a name, the Python interpreter will search the name in the existing variables scopes. It searchs considering an order such as Local Scope -> Enclosing Scope -> Global Scope -> Built-in Scope.

This search will definitely need some time.

The same thing happens when you use the construct dict() versus {} (an empty dict). Some people says that [] and {} are the most pythonic and readable ways to create empty lists/dicts. However, be carefull when using {} to create a dictionary with content:

this_is_a_set = {5}
this_is_a_dict = {}

The first one creates a set with one element, the second creates an empty dict and not a set.

Now you know. Prefere using [] instead of list() in your code.

For content in portuguese @aprendadatascience or https://aprendadatascience.com

References:

https://docs.python.org/3/library/timeit.html

--

--

Alex Barros
Alex Barros

Written by Alex Barros

Engenheiro da Computação. Mestre e Doutorando em Computação Aplicada. Coordenador do Escritório de Projetos e Processos no TRT8.

No responses yet