1

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.

asked Jun 2, 2015 at 4:32
2
  • 1
    I'd recommend reading nedbatchelder.com/text/names.html Commented Jun 2, 2015 at 6:22
  • +1 @jonrsharpe I was looking for that link! Commented Jun 2, 2015 at 19:34

1 Answer 1

7

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() ]
answered Jun 2, 2015 at 4:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.