Python language basics 29: passing the reference value into a function
July 12, 2015 4 Comments
Introduction
In the previous post we looked at the effects of modifying the value of an object. We saw the difference between mutable and immutable objects. Immutable objects cannot be changed directly in memory whereas mutable objects can. You need to keep in mind that if two object variables reference the same value then changing one variable value will also change the value of all other references.
In this post we’ll discuss what this behaviour means when objects are passed as arguments into functions. Functions will be able to modify the referenced argument which will also affect the object that was originally passed in. If you’re not aware of this behaviour it can cause irritation and buggy code.
Passing objects by reference
Say you have a dictionary object and a function that modifies an incoming dictionary object. Here’s the function:
def modify_dictionary(dictionary): dictionary["XL"] = "Extra large" return dictionary
Suppose that you want to call the above function and pass in your dictionary object. However, you don’t want to modify the dictionary that was passed into the function. A naive solution could look like this:
myFirstDictionary = {"S": "Small", "M": "Medium", "L": "Large", "XL": "X-Large"} newDictionary = modify_dictionary(myFirstDictionary) print(myFirstDictionary) print(newDictionary)
What do you think the print statements will give you? The following:
{‘L’: ‘Large’, ‘M’: ‘Medium’, ‘XL’: ‘Extra large’, ‘S’: ‘Small’}
{‘L’: ‘Large’, ‘M’: ‘Medium’, ‘XL’: ‘Extra large’, ‘S’: ‘Small’}
The function even modified the original dictionary, i.e. myFirstDictionary. There are cases when this is exactly what you want to achieve.
This is the same behaviour we saw in the previous post:
myFirstDictionary = {"S": "Small", "M": "Medium", "L": "Large", "XL": "X-Large"} mySecondDictionary = myFirstDictionary myFirstDictionary["S"] = "Smallish" myFirstDictionary["XXL"] = "XX-Large" print(myFirstDictionary) print(mySecondDictionary)
myFirstDictionary will be passed into the modify_dictionary function by reference. Just like we saw in the previous post Python won’t magically create a copy of myFirstDictionary when the modify_dictionary is called. If you want to make sure that your original object remains intact then it’s your responsibility to ensure that in code.
One solution is to create a so-called deep copy of the object. A deep copy is a copy where we copy every single property of the object so that two variables reference different values even if the values are otherwise identical.
A deep-copy function for a dictionary can look like this:
def deep_copy_dictionary(dictionary): deep_copy = {} for item in dictionary: deep_copy[item] = dictionary[item] return deep_copy
There’s nothing special in here. We just copy each key-value pair of the dictionary argument into another dictionary and return the copy. Here’s one way to use the copy function:
myFirstDictionary = {"S": "Small", "M": "Medium", "L": "Large", "XL": "X-Large"} copy = deep_copy_dictionary(myFirstDictionary) newDictionary = modify_dictionary(copy) print(myFirstDictionary) print(newDictionary)
myFirstDictionary will be left intact:
{‘M’: ‘Medium’, ‘XL’: ‘X-Large’, ‘L’: ‘Large’, ‘S’: ‘Small’}
{‘M’: ‘Medium’, ‘S’: ‘Small’, ‘L’: ‘Large’, ‘XL’: ‘Extra large’}
Read all Python-related posts on this blog here.
Nice post. Just a small addendum, if I may: your function
deep_copy_dictionary
isn’t exactly deep copy, as it will copy the reference of sub-dictionaries (dictionaries inside of the dictionary passed as a parameter), instead of copying all their fields as well.You can easily fix this by changing line 4 of
deep_copy_dictionary
to:Alternatively (and a more Pythonic way), you could use the implemented
copy
util:Cheers!
Great, thanks for your correction. I’m new to Python so any expert comments are welcome. //Andras
Of course! Keep up with the awesome work, dude. 🙂
Reblogged this on Dinesh Ram Kali..