Passing Arguments to defaultdict
I know it feels like I’ve been saying that a lot, but it really is one of the key points here. However, that’s a little bit inflexible, right? You might sometimes want to supply different arguments to
There are two ways of doing this. One is using
lambda functions, and the other one is using
functools.partial(). Let’s start with
lambda functions. Here we are back in the terminal, and the very first thing I’m going to do is import
collections so it’s available to me here. Okay.
So, imagine a scenario where you want to create a function which generates a default value in a
defaultdict. The function does some very basic processing and then it returns a value. You could have a function which is something like this.
I am creating a
defaultdict here. It’s called
def_dict, I’m calling
defaultdict(), and as a first argument—and remember, the first argument is what gets passed to
defaultdict()—I’m passing a
lambda function. And what that contains is this
factory() function which I just created, and I’m giving it a
'default value' here.
So let’s see what happens here when I try to access a missing value. My dictionary is completely empty, I can access anything I want. I’ll go with a string
'a' and this returns
'DEFAULT VALUE' in uppercase.
The notation is
<the name of my defaultdict>.default_factory and then I set a new value here. I’m reusing my
factory() function, which I had defined up here, but this time I’m passing a different input parameter.
But watch what happens when I try to access a different missing key. I already tried
'a', let’s try
'b' this time. And that gives me
'ANOTHER DEFAULT VALUE'. If I look at my
def_dict now it has two entries and they both have different default values, which were both generated using
.default_factory. In both cases,
.default_factory() triggered this
lambda function, but in the two cases I had passed different arguments to that function.
So that’s when you want different string values, but what about when you want different integer values? Remember, if you pass
int as the callable to
.default_factory, it’s always generating a
0, but we can get around this by doing something like in the following example.
Now what I’m going to do is I’m going to iterate through these numbers in my list. And each time I don’t already have that
number in my dictionary, I’m going to add that
number by multiplying it with
So the first time each of these numbers has been encountered, an entry was created with just
1 mapped to that number, but then each additional time that number has been multiplied by the value which was there. So that’s how
lambda can be useful, but what about
It behaves similar to when you call a function and pass it arguments and keywords, and you can take advantage of this behavior to pass arguments to
.default_factory. This is easier to grasp if I showed you an example.
Here we are back in the REPL and keep in mind that a bit above I had created this function. So I have this function
factory(), which takes an argument and returns the same argument but in uppercase.
And as a
default_factory, I’m passing
partial(). And as arguments to
partial(), I’m passing first my
factory function—so, the function which I had up here, which returns uppercase arguments—and I’m passing
'default value' as an argument, which in turn will get passed as an argument to
Let’s see what this gives us. My
defaultdict is empty but if I try to access a missing key, such as the key
'a'—or the key
'b', which is closer, you see this gives me
'DEFAULT VALUE'. Remember with lambdas I showed you you can update what is being passed to
.default_factory, and you do this by taking advantage of the fact that
.default_factory is just an attribute of your
defaultdict, so you can update it as we did here.
Well, I can do the same thing with
partial(). I can do something like this, where I’m updating
.default_factory. I’m again passing
partial() to it, I am again passing the
factory() function, but this time I’m passing a different argument.
then I get
'ANOTHER DEFAULT VALUE'. So what I’ve done is I’ve updated the arguments which I’m passing to
.default_factory. And if I now have a look at my
defaultdict, you can see I have two entries—one for
'DEFAULT VALUE' and one for
'ANOTHER DEFAULT VALUE'.
Those were the two ways you can pass arguments to
defaultdict. You can take advantage of
lambda and you can take advantage of
functools.partial(). In both cases, what you would be doing is you would be updating
.default_factory as an attribute of your
defaultdict. Okay. In the next lesson, I’m going to be going over a brief summary of everything we’ve looked at in this course. I’ll see you there!
Become a Member to join the conversation.