DefaultDicts are useful objects to be able to have a dictionary that can create new keys on the fly with a callable function used to define the default value. eg. Using str
to make an empty string the default.
>>> food = defaultdict(str)
>>> food['apple']
''
You can also use lambda to make an expression be the default value.
>>> food = defaultdict(lambda: "No food")
>>> food['apple']
'No food'
However you can't pass any parameters to this lambda function, that causes an error when it tries to be called, since you can't actually pass a parameter to the function.
>>> food = defaultdict(lambda x: "{} food".format(x))
>>> food['apple']
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
food['apple']
TypeError: <lambda>() takes exactly 1 argument (0 given)
Even if you try to supply the parameter
>>> food['apple'](12)
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
food['apple']
TypeError: <lambda>() takes exactly 1 argument (0 given)
How could these lambda functions be responsive rather than a rigid expression?
Using a variable in the expression can actually circumvent this somewhat.
>>> from collections import defaultdict
>>> baseLevel = 0
>>> food = defaultdict(lambda: baseLevel)
>>> food['banana']
0
>>> baseLevel += 10
>>> food['apple']
10
>>> food['banana']
0
The default lambda expression is tied to a variable that can change without affecting the other keys its already created. This is particularly useful when it can be tied to other functions that only evaluate when a non existant key is being accessed.
>>> joinTime = defaultdict(lambda: time.time())
>>> joinTime['Steven']
1432137137.774
>>> joinTime['Catherine']
1432137144.704
>>> for customer in joinTime:
print customer, joinTime[customer]
Catherine 1432137144.7
Steven 1432137137.77