【问题标题】:Dynamic dict value access with dot separated string使用点分隔字符串的动态 dict 值访问
【发布时间】:2016-08-08 15:01:12
【问题描述】:

我正在使用 Python 3.5.1

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

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 方式可以做到这一点,但我就是找不到。我已经浏览了文档,但无济于事。如果有人对我如何做到这一点有任何建议,将不胜感激。谢谢!

【问题讨论】:

  • 出于好奇,您为什么认为使用 split() 会变得一团糟?这是我首先想到的。
  • 我也有同样的想法。如果点是分隔符,那么我看不出不使用split('.') 的原因。

标签: python python-3.x


【解决方案1】:

你可以使用递归:

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()。但也许你认为它不那么凌乱?

【讨论】:

    【解决方案2】:

    我发现做到这一点的最简单方法,即通过“点字符串”使用“键路径”获取值是使用替换和评估:

    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解决方案你不需要安装其他库

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-11
      • 2011-09-13
      相关资源
      最近更新 更多