Shared References and Equality
Question:
Using Python 3.4 and working through examples in a book by O’Reily.
The example shows:
A = ['spam']
B = A
B[0] = 'shrubbery'
Result after running print A
:
'shrubbery'
Now my thought process is thatA
was defined but never changed.
This example yields a different result
A = 'string'
B = A
B = 'dog'
This is the result after running print A
:
'string'
Can someone explain?
Answers:
In the first example, you are modifying the list referenced by B
.
Doing:
B[0] = 'shrubbery'
tells Python to set the first item in the list referenced by B
to the value of 'shrubbery'
. Moreover, this list happens to be the same list that is referenced by A
. This is because doing:
B = A
causes B
and A
to each refer to the same list:
>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>
So, any changes to the list referenced by B
will also affect the list referenced by A
(and vice-versa) because they are the same object.
The second example however does not modify anything. Instead, it simply reassigns the name B
to a new value.
Once this line is executed:
B = 'dog'
B
no longer references the string 'string'
but rather the new string 'dog'
. The value of A
meanwhile is left unchanged.
I hope you could understand it with this way 🙂
As you see in first method, both of them refers to same list
, second one different.So in second way changes not effects on another one.
Here are the differences between the two:
Here’s a step by step analysis:
A = ['spam']
"A points to a list whose first element, or A[0], is 'spam'."
B = A
"B points to what A points to, which is the same list."
B[0] = 'shrubbery'
"When we set B[0] to 'shrubbery', the result can be observed in the diagram.
A[0] is set to 'shrubbery' as well."
print (A):
A = 'string'
"A points to 'string'."
B = A
"B points to what A points to, which is 'string'."
B = 'dog'
"Oh look! B points to another string, 'dog', now.
So does what A points to change? No."
The result can be observed in the diagram.
print (A):
As is the case in most modern dynamic languages, variables in python are actually references which are sort of like C pointers. This means that when you do something like A = B
(where A and B are both variables), you simply make A point to the same location in memory as B.
In the first example you are mutating (modifying) an existing object in place — this is what the variable_name[index/key] = value
syntax does. Both A and B continue to point at the same thing, but this things first entry is now ‘shrubbery’, instead of ‘spam’.
In the second example, you make B point at a different (new at this point) object when you say B = 'dog'
.
Mutable objects are Lists while Strings are immutable that’s why you can change the memory address and the lists itself but not the string.
We are talking here about shared references and mutable / immutable objects . When you do B = A, both variables points to same memory address ( shared reference) .
First case , list is a mutable object ( it’s state can be change ) but object memory address remains the same . So if you change it’s state , then the other variable will see those changes as it points to same memory address .( A and B have same value as they point to same object in memory )
Second case , string is immutable ( you cannot change it ) .By doing
B = ‘dog’ , basically you create another object and now B points to another object ( another memory address ) . In this case A still points to same old memory reference ( A and B have different values )
Using Python 3.4 and working through examples in a book by O’Reily.
The example shows:
A = ['spam']
B = A
B[0] = 'shrubbery'
Result after running print A
:
'shrubbery'
Now my thought process is thatA
was defined but never changed.
This example yields a different result
A = 'string'
B = A
B = 'dog'
This is the result after running print A
:
'string'
Can someone explain?
In the first example, you are modifying the list referenced by B
.
Doing:
B[0] = 'shrubbery'
tells Python to set the first item in the list referenced by B
to the value of 'shrubbery'
. Moreover, this list happens to be the same list that is referenced by A
. This is because doing:
B = A
causes B
and A
to each refer to the same list:
>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>
So, any changes to the list referenced by B
will also affect the list referenced by A
(and vice-versa) because they are the same object.
The second example however does not modify anything. Instead, it simply reassigns the name B
to a new value.
Once this line is executed:
B = 'dog'
B
no longer references the string 'string'
but rather the new string 'dog'
. The value of A
meanwhile is left unchanged.
I hope you could understand it with this way 🙂
As you see in first method, both of them refers to same list
, second one different.So in second way changes not effects on another one.
Here are the differences between the two:
Here’s a step by step analysis:
A = ['spam']
"A points to a list whose first element, or A[0], is 'spam'."
B = A
"B points to what A points to, which is the same list."
B[0] = 'shrubbery'
"When we set B[0] to 'shrubbery', the result can be observed in the diagram.
A[0] is set to 'shrubbery' as well."
print (A):
A = 'string'
"A points to 'string'."
B = A
"B points to what A points to, which is 'string'."
B = 'dog'
"Oh look! B points to another string, 'dog', now.
So does what A points to change? No."
The result can be observed in the diagram.
print (A):
As is the case in most modern dynamic languages, variables in python are actually references which are sort of like C pointers. This means that when you do something like A = B
(where A and B are both variables), you simply make A point to the same location in memory as B.
In the first example you are mutating (modifying) an existing object in place — this is what the variable_name[index/key] = value
syntax does. Both A and B continue to point at the same thing, but this things first entry is now ‘shrubbery’, instead of ‘spam’.
In the second example, you make B point at a different (new at this point) object when you say B = 'dog'
.
Mutable objects are Lists while Strings are immutable that’s why you can change the memory address and the lists itself but not the string.
We are talking here about shared references and mutable / immutable objects . When you do B = A, both variables points to same memory address ( shared reference) .
First case , list is a mutable object ( it’s state can be change ) but object memory address remains the same . So if you change it’s state , then the other variable will see those changes as it points to same memory address .( A and B have same value as they point to same object in memory )
Second case , string is immutable ( you cannot change it ) .By doing
B = ‘dog’ , basically you create another object and now B points to another object ( another memory address ) . In this case A still points to same old memory reference ( A and B have different values )