wonderbeyond
9/9/2015 - 9:51 AM

Get deep item from dict

deep get/set item in python dict

def deep_get(data, key, default=None):
    value = data
    try:
        for key in key.split('.'):
            if isinstance(value, dict):
                value = value[key]
                continue
            return default
    except KeyError:
        return default
    else:
        return value


def deep_set(d, key, value):
    dd = d
    keys = key.split('.')
    latest = keys.pop()
    for k in keys:
        dd = dd.setdefault(k, {})
    dd.setdefault(latest, value)


if __name__ == '__main__':
    test_data = {
        'name': 'wonder',
        'contact': {
            'phone': 110,
            'sns': {
                'qq': {
                    'code': 112,
                }
            }
        },
    }

    assert deep_get(test_data, 'name') == 'wonder'
    assert deep_get(test_data, 'english_name') == None
    assert deep_get(test_data, 'contact.phone') == 110
    assert deep_get(test_data, 'contact.phone.mobile') == None
    assert deep_get(test_data, 'contact.sns.qq.code') == 112
    assert deep_get(test_data, 'other1.other2.other3') == None
    assert deep_get(None, 'name') == None
    assert deep_get(100, 'name') == None
    assert deep_get('some', 'name') == None
    assert deep_get('some', 'name', 'wonder') == 'wonder'