Python allows arguments to have default values when defining a function.
The function below retrieves a value by specifying a key to the dictionary, but returns the default value 0 if the dictionary does not contain a key.
Python
def get(dic, key, default = 0):
if key in dic:
return dic[key]
else:
return default
let's do it.
Python
#Prepare a dictionary
times_in_PPAP = {"pen": 2, "pineapple": 1, "apple": 1}
print "pen:\t", get(times_in_PPAP, "pen")
print "apple:\t", get(times_in_PPAP, "apple")
print "banana:\t", get(times_in_PPAP, "banana")
result
pen: 2
apple: 1
banana: 0
Since pen and apple are in the dictionary, their values are returned. Since banana is not included in the dictionary, the default value of 0 is returned.
There is no problem so far. Now consider the following case.
Python
dict_PPAP = {"PP": ["pen", "pineapple"], "AP": ["apple", "pen"],
"PPAP": ["pen", "pineapple", "apple", "pen"]}
This dictionary is a dictionary that stores an array of the corresponding prototypes for the acronym. Let's write a function similar to the above for this dictionary.
Python
def restore_acronym(dic, key, default = []):
if key in dic:
return dic[key]
else:
return default
I will try it.
Python
print "PP:", restore_acronym(dict_PPAP, "PP")
print "AP:", restore_acronym(dict_PPAP, "AP")
print "PA:", restore_acronym(dict_PPAP, "PA")
result
PP: ['pen', 'pineapple']
AP: ['apple', 'pen']
PA: []
The PP and AP are included in the dictionary, so the original array is returned. For PA, the default empty array is returned because it is not included in the dictionary. I got the results I wanted.
However, using a function written this way can have surprising results. Let's get the default empty array from this function and add some elements as follows:
Python
my_list = restore_acronym(dict_PPAP, "PA")
print my_list
my_list.append("pico")
my_list.append("taro")
print my_list
result
[]
['pico', 'taro']
This operation seems to be fine, but it has surprising consequences. After this operation, try to get the default value by specifying a key that is not included in the dictionary (for example, BANANA).
Python
print "BANANA:", restore_acronym(dict_PPAP, "BANANA")
result
BANANA: ['pico', 'taro']
You can see that the effect of the previous operation remains in the default value.
This is because the default arguments for Python functions are evaluated only once when the module is loaded.
For example, consider the following function.
Python
from datetime import datetime
def my_log(message, timestamp = datetime.now()):
print "{timestamp}: {message}".format(timestamp = timestamp, message = message)
This function is intended to output the time stamp at that time when outputting the log message. However, when I actually run it, it looks like this:
Python
from time import sleep
my_log("0 sec")
sleep(1)
my_log("1 sec")
result
2016-12-31 23:59:59: 0 sec
2016-12-31 23:59:59: 1 sec
The same time stamp is displayed even though 1 second has passed. As mentioned above, the default arguments are evaluated only once when the function loads. Therefore, the default argument stores the time stamp when the function is loaded, and the time stamp does not change each time the function is called.
To get this function to work as intended, use None
and modify it as follows:
Python
def my_log2(message, timestamp = None):
if timestamp is None:
timestamp = datetime.now()
print "{timestamp}: {message}".format(timestamp = timestamp, message = message)
my_log2("0 sec")
sleep(1)
my_log2("1 sec")
result
2016-12-31 23:59:59: 0 sec
2017-01-01 00:00:00: 1 sec
By specifying None
as the default argument and bringingtimestamp = datetime.now ()
inside the function, the timestamp is obtained for each function call.
This solved the timestamp problem.
Now let's get back to the PPAP issue.
In this case, since an empty array was specified as the default argument, one empty array object was created when the function was loaded, and that object was reused, so the problem was that changes to that empty array were saved.
This can also be resolved by specifying None
as the default argument.
Python
def restore_acronym2(dic, key, default = None):
if default is None:
default = []
if key in dic:
return dic[key]
else:
return default
Now every time you call a function, an empty array of objects will be created. In fact, getting the default empty array and adding elements to it has no effect on the next default call.
Python
my_list2 = restore_acronym2(dict_PPAP, "PA")
print my_list2
my_list2.append("pico")
my_list2.append("taro")
print my_list2
print "BANANA:", restore_acronym2(dict_PPAP, "BANANA")
result
[]
['pico', 'taro']
BANANA: []
Note that in Python, setting a mutable object as the default argument of a function can cause unexpected bugs.
Enjoy!
Recommended Posts