Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert nested dictionary to defaultdict?

How can I convert nested dictionary to nested defaultdict?

dic = {"a": {"aa": "xxx"}}
default = defaultdict(lambda: None, dic)
print(default["dummy_key"])  # return None
print(default["a"]["dummy_key"])  # KeyError
like image 844
Maiko Ohkawa Avatar asked Apr 25 '18 03:04

Maiko Ohkawa


People also ask

How do I convert a nested list to a dictionary?

Converting a Nested List to a Dictionary Using Dictionary Comprehension. We can convert a nested list to a dictionary by using dictionary comprehension. It will iterate through the list. It will take the item at index 0 as key and index 1 as value.

How do I remove nested dictionary?

To remove an element from a nested dictionary, use the del() method.

How do you use nested dictionary?

Addition of elements to a nested Dictionary can be done in multiple ways. One way to add a dictionary in the Nested dictionary is to add values one be one, Nested_dict[dict][key] = 'value'. Another way is to add the whole dictionary in one go, Nested_dict[dict] = { 'key': 'value'}.

Is it possible to make nested dictionary?

You can create a nested dictionary in Python by placing comma-separated dictionaries within curly braces {}. A Python nested dictionary allows you to store and access data using the key-value mapping structure within an existing dictionary.


Video Answer


1 Answers

You need to either loop or recurse over the nested dictionary, through all of its levels.

Unless it's potentially ridiculously deep (as in hundreds of levels), or so wide that small performance factors make a difference, recursion is probably simplest here:

def defaultify(d):
    if not isinstance(d, dict):
        return d
    return defaultdict(lambda: None, {k: defaultify(v) for k, v in d.items()})

Or if you want it to work with all mappings, not just dicts, you could use collections.abc.Mapping instead of dict in your isinstance check.


Of course this is assuming you have a pure nested dict. If you've got, say, something you parsed from a typical JSON response, where there might be dicts with list values with dict elements, you have to handle the other possibilities too:

def defaultify(d):
    if isinstance(d, dict):
        return defaultdict(lambda: None, {k: defaultify(v) for k, v in d.items()})
    elif isinstance(d, list):
        return [defaultify(e) for e in d]
    else:
        return d

But if this actually is coming from JSON, it's probably better to just use your defaultdict as an object_pairs_hook while the JSON is being parsed, rather than parsing it to a dict and then converting it to a defaultdict later.

There's an example in the docs of using an OrderedDict in place of dict, but that won't quite work for us—unlike OrderedDict and dict, defaultdict can't just take an iterable of pairs as its only argument; it needs the default value factory first. So we can bind that in, using functools.partial:

d = json.loads(jsonstring, object_hook_pairs=partial(defaultdict, lambda: None))

And so on.

like image 166
abarnert Avatar answered Oct 05 '22 23:10

abarnert