使用点分隔字符串进行动态字典值访问

时间:2016-08-08 15:01:13

标签: python python-3.x

我正在使用Python 3.5.1

所以我要做的就是在dict中传入一个点分隔的字符串,表示键的路径和默认值。我想检查密钥是否存在,如果不存在,请提供默认值。这个问题是我想要访问的密钥可以嵌套在其他dicts中,直到运行时才会知道。所以我想要做的是这样的事情:

def replace_key(the_dict, dict_key, default_value):
    if dict_key not in the_dict:
       the_dict[dict_key] = default_value
    return the_dict

some_dict = {'top_property': {'first_nested': {'second_nested': 'the value'}}}
key_to_replace = 'top_property.first_nested.second_nested'
default_value = 'replaced'
#this would return as {'top_property': {'first_nested': {'second_nested': 'replaced'}}}
replace_key(some_dict, key_to_replace, default_value) 

我正在寻找的是一种方法来做到这一点,而不必分开'。'在字符串中并迭代可能的键,因为这可能会变得混乱。我宁愿不必使用第三方库。我觉得有干净的Pythonic方式来做这个,但我找不到它。我已经挖过文档,但无济于事。如果有人对我如何做到这一点有任何建议,我将非常感激。谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用递归:

def replace_key(the_dict, dict_keys, default_value):
    if dict_keys[0] in the_dict:
        if len(dict_keys)==1:
            the_dict[dict_keys[0]]=default_value
        else:
            replace_key(the_dict[dict_keys[0]], dict_keys[1:],default_value)
    else:
        raise Exception("wrong key")


some_dict = {'top_property': {'first_nested': {'second_nested': 'the value'}}}
key_to_replace = 'top_property.first_nested.second_nested'
default_value = 'replaced'
#this would return as {'top_property': {'first_nested': {'second_nested': 'replaced'}}}
replace_key(some_dict, key_to_replace.split("."), default_value)

但它仍然使用split()。但也许你认为它不那么混乱?

答案 1 :(得分:0)

我发现执行此操作的最简单方法,即使用“点路径”通过“键路径”获取值是使用replace和eval:

for key in pfields:
    if key.find('.') > 0:
        key = key.replace(".", "']['")
    try:
        data = str(eval(f"row['{key}']"))
    except KeyError:
        data = ''

这是按键的示例:

lfields = ['cpeid','metadata.LinkAccount','metadata.DeviceType','metadata.SoftwareVersion','mode_props.vfo.CR07.VIKPresence','mode_props.vfo.CR13.VIBHardVersion']

使用此 raw 解决方案,您无需安装其他库