Brian
Brian

Reputation: 161

unexpected behaviour of nested lists in python

I have a nested list called basic and I want to change one of its entries. I had assumed the following behaviour:

expected = [ [9],[0] ]
unexpected = [ [9],[9] ]
basic = [ [0],[0] ]
basic[0][0] = 9
print(basic == expected) # this is true

However, a slight modification gives a surprising output:

l = [0]
modified = [ l, l ]
modified[0][0] = 9
print(modified == expected) # this is false
print(modified == unexpected) # this is true

If your list is defined the second way, the assignment sets the whole column to 9.

Is this behaviour by design? If so, why? I can find nothing in the docs about it.

Upvotes: 1

Views: 146

Answers (1)

Jace Browning
Jace Browning

Reputation: 12662

In your first example:

basic = [ [0],[0] ]

you have created a list object containing two different list objects. You can see that they are different objects via id() or identity:

assert id(basic[0]) != id(basic[1])

assert basic[0] is not basic[1]

In your second example:

l = [0]
modified = [ l, l ]

you have placed the same list object into another list two times. Both list indicies refer to the same object:

assert id(basic[0]) == id(basic[1])

assert basic[0] is basic[1]

So, yes. This is how variables (and the objects they point to) work in Python.

To get the expected behavior, you need to create separate list objects:

modified = [ l.copy(), l.copy() ]

Upvotes: 7

Related Questions