How to Pythonically map content from one dict to another in a fail safe manner?

I've got one dict from an api:

initial_dict = {
    "content": {
        "text":
    },
    "meta": {
        "title": "something",
        "created": "2016-03-04 15:30",
        "author": "Pete",
        "extra": {
            "a": 123,
            "b": 456
        }
    }
}

and I need to map this to another dict:

new_dict = {
    "content_text": initial_dict['content']['text'],
    "meta_title": initial_dict['meta']['title'],
    "meta_extras": {
        "time_related": {
            initial_dict['meta']['created']
        },
        "by": initial_dict['meta']['author']
    }
}

The problem is that not all fields are always in the initial_dict. I can of course wrap the whole creation of new_dict into a try/except , but then it would fail if one of the initial fields doesn't exist.

Is there no other way than creating a try/except for each and every field I add to the new_dict ? In reality the dict is way bigger than this (about 400 key/value pairs), so this will become a mess quite fast.

Isn't there a better and more pythonic way of doing this?


How about using dict.get ? Instead of throwing an error, this returns None if the key isn't in the dictionary.

new_dict = {
    "content_text": initial_dict['content'].get('text'),
    "meta_title": initial_dict['meta'].get('title'),
    "meta_extras": {
        "time_related": {
            initial_dict['meta'].get('created')
        },
        "by": initial_dict['meta'].get('author')
    }
}

If this goes deeper than one level, you can do some_dict.get('key1', {}).get('key2') as was suggested in the comments.

Converting the original dict to a defaultdict is also an option, which allows you to keep using the [] notation (more practical than having to chain get methods):

from collections import defaultdict
def to_defaultdict(d):
    return defaultdict(lambda: None, ((k, to_defaultdict(v) if isinstance(v, dict) else v)
                                      for k, v in d.items()))
initial_dict = to_defaultdict(initial_dict)

You can then filter out the None values:

def filter_dict(d):
    return dict((k, filter_dict(v) if isinstance(v, dict) else v)
                for k, v in d.items() if v is not None)
new_dict = filter_dict(new_dict)
链接地址: http://www.djcxy.com/p/31704.html

上一篇: 只从元组列表中获取整数python 3

下一篇: 如何以一种故障安全的方式将内容从一个词典用Python语言映射到另一个词典?