You are on page 1of 1

Chapter 200: Common Pitfalls

Python is a language meant to be clear and readable without any ambiguities and unexpected behaviors.
Unfortunately, these goals are not achievable in all cases, and that is why Python does have a few corner cases
where it might do something different than what you were expecting.

This section will show you some issues that you might encounter when writing Python code.

Section 200.1: List multiplication and common references


Consider the case of creating a nested list structure by multiplying:

li = [[]] * 3
print(li)
# Out: [[], [], []]

At first glance we would think we have a list of containing 3 different nested lists. Let's try to append 1 to the first
one:

li[0].append(1)
print(li)
# Out: [[1], [1], [1]]

1 got appended to all of the lists in li.

The reason is that [[]] * 3 doesn't create a list of 3 different lists. Rather, it creates a list holding 3 references
to the same list object. As such, when we append to li[0] the change is visible in all sub-elements of li. This is
equivalent of:

li = []
element = [[]]
li = element + element + element
print(li)
# Out: [[], [], []]
element.append(1)
print(li)
# Out: [[1], [1], [1]]

This can be further corroborated if we print the memory addresses of the contained list by using id:

li = [[]] * 3
print([id(inner_list) for inner_list in li])
# Out: [6830760, 6830760, 6830760]

The solution is to create the inner lists with a loop:

li = [[] for _ in range(3)]

Instead of creating a single list and then making 3 references to it, we now create 3 different distinct lists. This,
again, can be verified by using the id function:

print([id(inner_list) for inner_list in li])


# Out: [6331048, 6331528, 6331488]

GoalKicker.com – Python® Notes for Professionals 762

You might also like