3

I am starting to learn Python and have run across a piece of code that I'm hoping one of you can help me understand.

from collections import defaultdict
dd_dict = defaultdict(dict)
dd_dict["Joel"]["City"] = "Seattle"

result:

{ "Joel" : { "City" : Seattle"}}

The part I am having a problem with is the third line. Could someone please explain to me what is happening here?

  • 1
    A `defaultdict` is a `dict` whose keys "default" to values if a key has not been set yet. You basically have a dictionary of a dictionary (third line). – Abdou Jan 04 '17 at 02:02

6 Answers6

5

The third line inserts a dictionary inside a dictionary. By using dict as a default value in default dict you are telling python to initialize every new dd_dict value with an empty dict. The above code is equivalent to

dd_dict["Joel"] = {}
dd_dict['Joel"]["City"] = "Seattle"

If you didn't use default dict the second line would have raised a key error. So default dicts are a way of avoiding such errors by initializing the default value of your data structure.

Yonas Kassa
  • 3,362
  • 1
  • 18
  • 27
3

From the documentation of defaultdict:

If default_factory is not None, it is called without arguments to provide a default value for the given key, this value is inserted in the dictionary for the key, and returned.

Since "Joel" doesn't exist as key yet the dd_dict["Joel"] part creates an empty dictionary as value for the key "Joel". The following part ["City"] = "Seattle" is just like adding a normal key-value pair a dictionary - in this case the dd_dict["Joel"] dictionary.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
2

The first argument provides the initial value for the default_factory attribute; it defaults to None. If default_factory is not None, it is called without arguments to provide a default value for the given key, this value is inserted in the dictionary for the key, and returned.

dd_dict = defaultdict(dict)
dd_dict["Joel"]["City"] = "Seattle"

in you case, when you call dd_dict["Joel"], there is no such key in the dd_dict, this raises a KeyError exception. defaultdict has __missing__(key) protocol to handle this error, when it can not find the key, it will call the default_factory without arguments to provide a default value for the given key.

so when you call dd_dict["Joel"], this will give you a dict {}, then you add item ["City"] = "Seattle" to the empty dict, someting like:

{}["City"] = "Seattle"
宏杰李
  • 11,820
  • 2
  • 28
  • 35
0

When a key is accessed and is missing, the __missing__ method is accessed.

For a regular dict, a KeyError is raised

For a defaultdict, the object you passed as a parameter is created and accessed.

If you made a defaultdict(list), and tried to access a missing key, you would get a list back.

Example:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['missing']
[]
Vasili Syrakis
  • 9,321
  • 1
  • 39
  • 56
0

When you access a key of a defaultdict that does not exits, you will get what the function you supply returns.

In your case you supplied dict, therefore you get a new empty dictionary:

>>> dict()
{}

>>> from collections import defaultdict
... dd_dict = defaultdict(dict)
...
>>> dd_dict['Joel']
{}

Now you add your key-value pair to this dictionary:

>>> dd_dict["Joel"]["City"] = "Seattle"
"Joel" : { "City" : Seattle"}}
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
0

defaultdict(dict) returns a dictionary object that will return an empty dictionary value if you index into it with a key that doesn't yet exist:

>>> from collections import defaultdict
>>> dd_dict = defaultdict(dict)
>>> dd_dict
defaultdict(<class 'dict'>, {})
>>> dd_dict["Joel"]
{}
>>> dd_dict["anything"]
{}
>>> dd_dict[99]
{}

So the third line creates a key-value pair ("Joel", {}) in dd_dict, then sets the ("City", "Seattle") key-value pair on the empty dictionary.

It's equivalent to:

>>> dd_dict = defaultdict(dict)
>>> dd_dict["Joel"] = {}
>>> dd_dict
defaultdict(<class 'dict'>, {'Joel': {}})
>>> dd_dict["Joel"]["City"] = "Seattle"
>>> dd_dict
defaultdict(<class 'dict'>, {'Joel': {'City': 'Seattle'}})
Tom McDermott
  • 221
  • 1
  • 3