When to Use [] vs list() in Python: Performance, Readability, and Pitfalls
This article compares Python's literal [] and the list() constructor, examining their speed differences, readability implications, default‑argument pitfalls, object identity, and appropriate use cases such as creating empty lists, converting iterables, and avoiding mutable default parameters.
Fundamentals: [] vs list()
At first glance, both ways can create an empty list:
a = []
b = list()
print(a == b) # TrueSo far, everything works, but differences start to appear later.
Performance: Speed matters
In Python, the literal [] syntax is actually faster than calling list().
Performance test
import timeit
print(timeit.timeit('[]', number=1000000))
print(timeit.timeit('list()', number=1000000))On most machines, [] runs faster. Why? Because [] is a literal parsed directly by the interpreter, while list() is a function call that incurs extra overhead.
[] is a literal – it is parsed directly by the Python interpreter. list() is a function call – and function calls in Python add overhead.
If you care about micro‑optimizations (e.g., in tight loops), prefer [] over list().
Readability and intent
Sometimes the choice is about clarity rather than performance.
Consider the following code:
usernames = list() # Looks like you are creating an empty listvs: usernames = [] Many Python developers find [] more concise and "Pythonic". However, when you need to convert another iterable, list() becomes necessary: list('hello') # ['h', 'e', 'l', 'l', 'o'] So the decision is context‑dependent.
Function default value: [] trap
Let's talk about mutable default arguments – a common beginner pitfall in Python.
Wrong way
def append_item(item, lst=[]):
lst.append(item)
return lstYou might expect a new list each call, but the same list object is reused:
print(append_item('a')) # ['a']
print(append_item('b')) # ['a', 'b']Correct way
def append_item(item, lst=None):
if lst is None:
lst = list() # or lst = []
lst.append(item)
return lstBecause the default [] is evaluated only once at function definition time, using list() (or []) inside the function avoids the shared‑state trap.
Flexibility: list() can take arguments
Unlike [], list() can convert other iterables into a list:
list(range(3)) # [0, 1, 2]
list((1, 2, 3)) # [1, 2, 3]
list({1, 2, 3}) # [1, 2, 3]
list(map(str, [1, 2])) # ['1', '2']Trying the same with [] results in a TypeError: []( 'abc' ) # TypeError Therefore, list() is superior for data conversion.
Mutability is the same
Both creations produce mutable lists:
a = []
b = list()
a.append(1)
b.append(2)
print(a) # [1]
print(b) # [2]Once created, their behavior is identical; the difference lies in how you create them.
Object identity: not always the same
a = []
b = []
print(a is b) # FalseEach call to [] or list() returns a new object – no shared references.
[] == [] # True
[] is [] # FalseEquality checks values, identity checks memory addresses; keep this distinction in mind when using is and ==.
When to use []
Creating an empty list (performance advantage).
Better readability and conciseness.
Initializing new lists inside loops or functions.
Generally as the default constructor.
results = []When to use list()
Converting other iterables to a list.
Avoiding mutable default argument pitfalls (inside functions).
Explicitly expressing intent during data transformation.
Creating lists from generators or map objects.
names = list(map(str.upper, ['alice', 'bob']))Real case: list initialization in loops
This is a subtle but practical situation – initializing lists inside a loop.
Don't do this
output = []
for _ in range(3):
output.append([])Looks fine, but consider:
output = [[]] * 3
output[0].append(1)
print(output) # [[1], [1], [1]]The [] * 3 replicates the same list object, causing all entries to share modifications.
A better approach: output = [list() for _ in range(3)] or: output = [[] for _ in range(3)] This creates three independent lists.
Summary
In Python, [] and list() both create empty lists, but they differ significantly in performance, readability, flexibility, and object identity. In most cases, [] is the preferred way to create an empty list because it is shorter, faster, and idiomatic. However, list() is essential when converting other iterables to a list and when avoiding mutable default argument pitfalls inside functions. Understanding these differences helps you write more efficient and reliable Python code.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
