I can't find concise information about what is going on in this very simple program:
print 'case 1'
# a and b stay different
a = [1,2,3]
b = a
b = [4,5,6]
print 'a =',a
print 'b =',b
print
print 'case 2'
# a and b becomes equal
a = [1,2,3]
b = a
b[0] = 4
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:]
b[0] = 4
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:]
b[0] = 4
b[1] = 5
b[2][0] = 6 # this modifies b and a!!!
The output of this simple test is:
case 1
a = [1, 2, 3]
b = [4, 5, 6]
case 2
a = [4, 5, 6]
b = [4, 5, 6]
case 3
a = [1, 2, 3]
b = [4, 5, 6]
case 4
a = [1, 2, [6]]
b = [4, 5, [6]]
I clearly do not understand how python handles each case. Could any one provide a link so that I can read about it, or a short explanation of what is happening?
Thanks a lot.
This is a fantastic visualization tool for python code.
Run your code in it and everything should become clear in a minute.
There are two important things here:
When you find that both a
and b
are modified, then that's because both of them are pointing to the same object. You can do id(a)
and id(b)
to confirm this.
Regarding the examples, note that a[:]
will create a new object which is a copy of a
. However, it will be a shallow copy, not a deep copy. This explains why in example 4, you can still modify both a
and b
. They are pointing to different list objects, but one element is another list that is shared by both of them.
Case 1: The name b
is rebound.
Case 2: a
and b
are bound to the same object.
Case 3: A shallow copy of a
is bound to b
. The lists are different, but the objects within the list are the same.
Case 4: A shallow copy of a
is bound to b
, and then one of the objects is mutated.
Rebinding does not mutate, and mutation does not rebind.
print 'case 1'
# a and b stay different
a = [1,2,3]
b = a #At this point 'b' and 'a' are the same,
#just names given to the list
b = [4,5,6] #At this point you assign the name 'b' to a different list
print 'a =',a
print 'b =',b
print
print 'case 2'
# a and b becomes equal
a = [1,2,3] #At this point 'b' and 'a' are the same,
#just names given to the list
b = a
b[0] = 4 #From here you modify the list, since both 'a' and 'b'
#reference the same list, you will see the change in 'a'
b[1] = 5
b[2] = 6
print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:] #At this point you COPY the elements from 'a' into a new
#list that is referenced by 'b'
b[0] = 4 #From here you modify 'b' but this has no connection to 'a'
b[1] = 5
b[2] = 6
print 'a =',a
print 'b =',b
print
print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:] #At this point you COPY the elements from 'a' into a new
#list that is referenced by 'b'
b[0] = 4 #Same as before
b[1] = 5
b[2][0] = 6 # this modifies b and a!!! #Here what happens is that 'b[2]' holds
#the same list as 'a[2]'. Since you only modify the element of that
#list that will be visible in 'a', try to see it as cases 1/2 just
#'recursively'. If you do b[2] = 0, that won't change 'a'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With