I understand that they are both essentially the same thing, but in terms of style, which is the better (more Pythonic) one to use to create an empty list or dict?
-
I was wondering too if there's any mention of that in a PEP or something? After all, the Zen of Python states: "There should be one-- and preferably only one --obvious way to do it.". – LoneCodeRanger Mar 09 '23 at 16:48
-
I believe that declaring an empty list using list() is more Pythonic (aligns with PEP8 and The Zen philosophy). Facts: 1. there is no direct instruction in PEP 8 on how to do it. 2. list() form of declaration is easier to read for people with visual impairments. 3. If there is no explicit instruction in PEP 8, the code should be written in a way that is easily readable and understandable for other developers For example, from a distance, I have difficulty discerning which data structure is being declared: [], {}, or (). – Sergiusz Jul 06 '23 at 09:19
11 Answers
In terms of speed, it's no competition for empty lists/dicts:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
and for non-empty:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
Also, using the bracket notation lets you use list and dictionary comprehensions, which may be reason enough.

- 175,061
- 34
- 275
- 318

- 6,714
- 2
- 27
- 22
-
8Dict and list comprehensions can be done using the English names as well. Example: `list(i for i in range(10) if i % 2)` – Zags Jun 13 '14 at 19:37
-
4is there a reason why {} and [] are so much faster? I thought they were simply aliases. – Justin D. Nov 25 '15 at 03:44
-
1The timeit doesn't seem to give accurate time. As per the benchmark, it seems to take ~200ms which is way slower than normal http calls. Try running dict() normally in shell and then run timeit("dict()"), you would see visible difference in execution. – piyush May 26 '17 at 14:04
-
6@piyush Actually, the `timeit()` function reports the total amount of time to execute a specified number of iterations, which is `1000000` by default. So the examples above are the number of seconds to run the code snippet a million times. For example `timeit('dict()', number=1) // -> 4.0531158447265625e-06` (one iteration) while `timeit('dict()') // -> 0.12412905693054199`(a million iterations) – Greg Haskins Jun 06 '17 at 22:09
-
1@GregHaskins so in that case, I don't see one should worry about using dict() or {}, unless looping through a million records & using dict() in the loop. – piyush Jun 17 '17 at 09:24
-
a good explanation about that fact here: https://stackoverflow.com/questions/30216000/why-is-faster-than-list – Jean-François Fabre Dec 21 '17 at 13:10
-
@Zags That is **not** a list comprehension. That's a generator expression, which becomes a generator iterator, which is then passed to `list` as argument. – Kelly Bundy Aug 28 '23 at 08:01
In my opinion []
and {}
are the most pythonic and readable ways to create empty lists/dicts.
Be wary of set()
's though, for example:
this_set = {5}
some_other_set = {}
Can be confusing. The first creates a set with one element, the second creates an empty dict and not a set.

- 112,504
- 36
- 218
- 315
-
6`{}` always creates an empty dict. `{1,2,3}` creates a set in 2.7+ but is a syntax error in `2.6` and older versions. – ThiefMaster Apr 26 '11 at 13:20
-
2sorry? that's a variable with name `some_epic_set` that is pointing to an empty `dict` object... it's not an empty set. For an empty set you need to use `set()`. – 6502 Apr 26 '11 at 13:21
-
3@6502: Indeed, but it is a common pitfall that `{5}` creates a set with one element, `5` and `{}` is an empty dict. – orlp Apr 26 '11 at 13:24
-
1Wow, that was confusing. Still, it's not Fractal of Bad Design level of confusing. :-) – Prof. Falken Aug 21 '12 at 12:45
-
Can {} be used to make a set? This work in python 3.6? There is a way to make an empty set with {}? Thanks. – Ender Look May 26 '17 at 14:57
-
-
9@EnderLook: Actually, with [generalized unpacking](https://www.python.org/dev/peps/pep-0448/), you can use `{*()}` to make an empty `set` with literal syntax. I call it the one-eyed monkey operator. :-) – ShadowRanger Nov 09 '18 at 04:15
The dict literal might be a tiny bit faster as its bytecode is shorter:
In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()
In [4]: dis.dis(a)
1 0 BUILD_MAP 0
3 RETURN_VALUE
In [5]: dis.dis(b)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
Same applies to the list
vs []

- 310,957
- 84
- 592
- 636
-
8This assumes that BUILD_MAP and LOAD_GLOBAL are constant time and take the same amount of time. Highly unlikely. timeit gives a much better estimation. – Jamie Pate Jun 10 '14 at 15:53
-
1More likely, `CALL_FUNCTION` takes *at least* as much time as `BUILD_MAP` (the function being called essentially is `BUILD_MAP`), and `LOAD_GLOBAL` takes is just additional overhead. – chepner Nov 19 '19 at 17:18
-
@chepner But you will find that `list()` is still slower than `list;[]`. Although they do the same thing, function calls still need to follow some Python protocols, while bytecode calls the corresponding C function directly. – Mechanic Pig Nov 11 '22 at 08:20
Be careful list()
and []
works differently:
>>> def a(p):
... print(id(p))
...
>>> for r in range(3):
... a([])
...
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
... a(list())
...
139969725367296
139969725367552
139969725367616
list()
always creates a new object on the heap, but []
can reuse memory cells in many situations.
-
I suspect that this is because of the way Python function calls work, which requires the creation of argument tuple and possible dictionary, thus affecting memory reuse. – Mechanic Pig Nov 11 '22 at 08:16
-
1@MechanicPig But if I do `def list(): return []` first, then the `list()` version also always gives me the same address. – Kelly Bundy Aug 28 '23 at 08:10
-
1@KellyBundy I checked the source code and found that CPython did not perform any optimization on `list.__new__()`, and in 3.11, the inlining of the function object even caused your `list` function to be faster than the `list`'s own constructor, which disappointed me a bit. – Mechanic Pig Aug 28 '23 at 09:10
-
@MechanicPig What do you mean with inlining? And how much faster was it, and if you used timeit or so, did you try localizing the built-in (like doing `list_ = list` in the setup and then using that)? – Kelly Bundy Aug 28 '23 at 12:09
-
@KellyBundy 1) Function calls are inlined in Python 3.11: [inlined python function calls](https://docs.python.org/3/whatsnew/3.11.html#inlined-python-function-calls) 2) Yes, I localized it (`list = list`), but the built-in is still slower (the built-in is 48.7 ns ± 0.43 ns and the custom function is 46.4 ns ± 0.189 ns). – Mechanic Pig Aug 28 '23 at 13:12
-
@MechanicPig Thanks. Is `list = list` a typo, or how/where did you use that? – Kelly Bundy Aug 28 '23 at 14:52
-
@KellyBundy Sorry, what I said is not entirely correct. This is not localize, but doing `globals()['list'] = builtins.list` (which means that both constructor and function only need one dictionary search, and I think their efficiency is similar. Originally, the `list` needed to be searched from `globals()` first and then from the `builtins.__dict__`). I tested the time using the `%timeit` magic command in the IPython interactive console. – Mechanic Pig Aug 28 '23 at 15:08
-
@MechanicPig Ok, so not both local but both global and under the same name, which I guess is fair as well. – Kelly Bundy Aug 28 '23 at 15:52
In the case of difference between [] and list(), there is a pitfall that I haven't seen anyone else point out. If you use a dictionary as a member of the list, the two will give entirely different results:
In [1]: foo_dict = {"1":"foo", "2":"bar"}
In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]
In [3]: list(foo_dict)
Out [3]: ['1', '2']

- 3,990
- 6
- 30
- 43
-
You can get the same results as `[foo_dict]` by using `list((foo_dict,))`. The `list()` method takes an iterable as it's only parameter and iterates over it to add elements to the list. This will cause a similar pitfall by doing `list(some_list)` which will flatten the list. – sotrh Mar 26 '18 at 21:33
A difference between list()
and []
not mentioned by anyone, is that list()
will convert, for example a tuple, into a list. And []
will put said tuple into a list:
a_tuple = (1, 2, 3, 4)
test_list = list(a_tuple) # returns [1, 2, 3, 4]
test_brackets = [a_tuple] # returns [(1, 2, 3, 4)]

- 1,074
- 8
- 25
-
1Another difference: `list` accepts only iterables as parameters, e.g. `list(1)` gives a `TypeError: 'int' object is not iterable`. On the other hand `[1] ` returns a `list` with one element. – KevinYanesG Nov 28 '22 at 11:25
There is no such difference between list() and [] but if you use it with iterators, it gives us:
nums = [1,2,3,4,5,6,7,8]
In: print([iter(nums)])
Out: [<list_iterator object at 0x03E4CDD8>]
In: print(list(iter(nums)))
Out: [1, 2, 3, 4, 5, 6, 7, 8]

- 57
- 7
there is one difference in behavior between [] and list() as example below shows. we need to use list() if we want to have the list of numbers returned, otherwise we get a map object! No sure how to explain it though.
sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth)
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list
type(sth2[0]) # map
sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int

- 538
- 5
- 8
-
here seems to be an explanation of the behavior using example of the range() function >>> print(range(10)) # range(0, 10) range() behaves like a list, but it isn’t a list. It is an object which returns the successive items of from a sequence when you iterate over it, it doesn’t really make the list, saving space. such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. The function list() creates lists from iterables: >>> list(range(5)) # [0, 1, 2, 3, 4] – sebtac May 22 '18 at 03:45
-
1the consequence is that [] stores the iterable object; list() creates list from the same iterable – sebtac May 22 '18 at 03:50
One of the other differences between a list()
and []
list_1 = ["Hello World"] # is a list of the word "Hello World"
list_2 = list("Hello World") # is a list of letters 'H', 'e', 'l'...
Something to keep in mind...

- 452
- 5
- 24
A box bracket pair denotes one of a list object, or an index subscript, like my_List[x]
.
A curly brace pair denotes a dictionary object.
a_list = ['on', 'off', 1, 2]
a_dict = { on: 1, off: 2 }

- 158,662
- 42
- 215
- 303

- 446
- 4
- 8