References
When an object is assigned to another object in Python the object reference is copied and not the values themselves.
Ex:
list1 = []
list1.append( 4 )
print( list1 )
list2 = list1
list2.append( 3 )
print( list1 )
print( list2 )
Output:
[amittal@hills chapter11]$ python3 ref1.py
[4]
[4, 3]
[4, 3]
Initially "list1" is empty and then we append 4 and print the "list1" . Next we assign "list1" to "list2"
There are 2 functions we can use to check if the variables are pointing to the same item and what kind of item we have. One is "type" and the other is "id". Let us use the 2 functions in the above example.
Ex:
list1 = []
list1.append( 4 )
print( list1 )
list2 = list1
list2.append( 3 )
print ("Id of list1" , id(list1) , " Type of list1." , type(list1) )
print ("Id of list2", id(list2) , " Type of list2." , type(list2) )
print( list1 )
print( list2 )
Output:
[amittal@hills chapter11]$ python3 ref1a.py
[4]
Id of list1 139787670258312 Type of list1. <class 'list'>
Id of list2 139787670258312 Type of list2. <class 'list'>
[4, 3]
[4, 3]
The lists point to a single object in memory. When we modify one object using the "append" method then the object in memory is modified because list objects are mutable. We can modify them in place without creating a new object. However types such as integers and strings are not mutable and the behavior is different.
>>> a1 = b1 = 0
>>> id( a1 )
140226919643072
>>> id( b1 )
140226919643072
>>> b1 = b1 + 1
>>> id( b1 )
140226919643104
>>> b1
1
>>> a1
0
>>>
We assign the value 0 to the 2 variables a1 and b1 . At this point both the variables are pointing to the same object in memory as shown by the "id" function. Now we execute the statement:
b1 = b1 + 1
The expression "b1 + 1" creates a new integer object and that object with the value 1 gets assigned to b1" . We can see that the "id" is different and the the b1 value got changed but the value of a1 is still the same. It's not possible to change the value of an integer object in place ( in memory ). We can only change the value by assigning a new object to it. This is the same behavior for immutable types.
Memory Pool
Python implementation can decide to "reuse" literal string,
>>> a1 = "Test"
>>> b1 = "Test1"
>>> id( a1 )
140226920164968
>>> id ( b1 )
140226920165024
>>> b1 = "Test"
>>> id( b1 )
140226920164968
>>>
Initially the variables "a1" and "b1" point to different objects as shown by the "id" function. Then we assign "Test" to the variable "b1" . This does not create a new object for "b1' but rather uses the object "Test" from the pool .
Reserved Keywords
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
Notice that the types are not in the list of reserved words. So we can do :
Ex:
#int = 1
i1 = 2
if type(i1) == int:
print( "Is int" )
else:
print( "Not int" )
Assignment Statements
What does
[var1, var2] = [ "value1" , "Value2" ]
do ?
We know the values of the variables var1 and var2 get changed .
>>> [var1, var2] = [ "value1" , "Value2" ]
>>> var1
'value1'
>>> var2
'Value2'
But is "[var1, var2]" a list ? Yes it is. What are the elements of this list ?
>>> list1 = [var1, var2] = [ "value1" , "Value2" ]
>>> list1
['value1', 'Value2']
We can use the multiple assignment operator in the form :
a = b = c
The value of "c" is assigned to b and then the value of "c" is assigned to a .
First the values on the right hand side "value1" and "value2" get assigned to the variables var1 and var2 . The list "list1"
contains 2 values "value1" and "value2" . Then the same values "value1" and value2" in the list gets assigned to "list1" .
A list will not really contain variables but values for those variables.
The same technique can be used for tuples:
>>> tuple1 = (var1, var2) = ( "value1" , "Value2" )
>>> tuple1
('value1', 'Value2')
The number of arguments on the left hand side and the right hand side should match.
>>> var1 , var2 = "value1"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
However we can have the below:
>>> var1 = "value1" , "value2"
>>> var1
('value1', 'value2')
Now the value "value1" is not assigned to var1 but since we have 2 values on the right hand side separated by a comma Python thinks of it as a tuple and that tuple is assigned to var1 . When we print the value of var1 we get a tuple out. We can use the sequence assignment to exchange values of variables.
Ex:
>>> var1 = "value1"
>>> var2 = "value2"
>>> var1 , var2 = var2 , var1
>>> var1
'value2'
>>> var2
'value1'
We can do the above using a temp variable:
>>> var1 = "value1"
>>> var2 = "value2"
>>> temp = var1
>>> var1 = var2
>>> var2 = temp
>>> var1
'value2'
>>> var2
'value1'
>>>
If our variables contain integers then we can do without the "temp" variable.
>>> var1 = 5
>>> var2 = 7
>>> var1 = var1 + var2
>>> var2 = var1 - var2
>>> var1 = var1 - var2
>>> var1
7
>>> var2
5
We can also have assignment statements where the assignment is of different types.
Multiple Target Assignments
a = b = c = "spam"
is not
c = "spam"
b = c
and a = b
Rather the "spam" is assigned to a "temp" variables which is then assigned to c , b and a .
Ex:
list1 = ( a, b, c, d ) = "Test"
print( list1 )
Output:
Test
The contents of "list1" is not a tuple but the original string.
list1 = ( a, b, c, d ) = "Test"
print( list1 )
can be written as:
temp = "Test"
( a, b, c, d ) = temp
list1 = temp
print( list1 )