如何将键中嵌套的python字典值替换为以点分隔的字符串格式? 让我们考虑这个“StryKEY”字符串,用无穷多的点/级别来表示。

如何将键中嵌套的python字典值替换为以点分隔的字符串格式? 让我们考虑这个“StryKEY”字符串,用无穷多的点/级别来表示。,python,multidimensional-array,Python,Multidimensional Array,预期输出: a = { 'user': { 'username': 'mic_jack', 'name': { 'first': 'Micheal', 'last': 'Jackson' }, 'email': 'micheal@domain.com', #... #... Infinite level of another neste

预期输出:

a = {
    'user': {
        'username': 'mic_jack',    
        'name': {
            'first': 'Micheal',
            'last': 'Jackson'
        },
        'email': 'micheal@domain.com',

        #...
        #... Infinite level of another nested dict
    }     
}

str_key_1 = 'user.username=john'
str_key_2 = 'user.name.last=henry'
#...
#str_key_n = 'user.level2.level3...leveln=XXX'
我期待着应用“n”级别的嵌套键字符串的答案,而不是简单地静态地替换为
a['user']['username']='John'
。答案必须适用于任意数量的“虚线”字符串值

提前谢谢

有三个步骤:

  • 将键值对字符串分隔为完全限定的键,然后 价值观
  • 将关键点拆分为路径组件
  • 遍历字典以查找要更新的相关值
  • 下面是代码的示例:

    a = {
        'user': {
            'username': 'john',     # username, should be replace    
            'name': {
                'first': 'Micheal',
                'last': 'henry'     # lastname, should be replace 
            },
            'email': 'micheal@domain.com',
    
            ...
            ... # Infinite level of another nested dict
        }     
    }
    

    我将使用递归函数来实现这一点,假设您的键值字符串都是有效的:

    # Split by the delimiter, making sure to split once only
    # to prevent splitting when the delimiter appears in the value
    key, value = str_key_n.split("=", 1)
    
    # Break the dot-joined key into parts that form a path
    key_parts = key.split(".")
    
    # The last part is required to update the dictionary
    last_part = key_parts.pop()
    
    # Traverse the dictionary using the parts
    current = a
    while key_parts:
      current = current[key_parts.pop(0)]
    
    # Update the value
    current[last_part] = value
    
    我们的想法是遍历你的
    dict
    ,直到你点击最低的
    键,然后我们将我们的新值分配给最后一个键

    def assign_value(sample_dict, str_keys, value):
      access_key = str_keys[0]
    
      if len(str_keys) == 1:
        sample_dict[access_key] = value
      else:
        sample_dict[access_key] = assign_value(sample_dict[access_key], str_keys[1:], value)
    
      return sample_dict
    

    要使用
    assign_value
    ,您需要将原始密钥拆分为如上所示的密钥和值

    如果您同意使用exec()并修改str_键,您可以执行以下操作:

    if __name__ == "__main__":
      sample_dict = {
          'user': {
              'username': 'mic_jack',    
              'name': {
                  'first': 'Micheal',
                  'last': 'Jackson'
              },
              'email': 'micheal@domain.com'
          }     
      }
    
      str_key_1 = 'user.username=john'
      str_keys_1, value_1 = str_key_1.split('=')
      sample_dict = assign_value(sample_dict, str_keys_1.split('.'), value_1)
    
      print("result: {} ".format(sample_dict))
    
    
      str_key_2 = 'user.name.last=henry'
      str_keys_2, value_2 = str_key_2.split('=')
      sample_dict = assign_value(sample_dict, str_keys_2.split('.'), value_2)
    
      print("result: {}".format(sample_dict))
    

    真的感觉像一个,你想实现什么?你是说你想通过n个嵌套dicts为每个可能的深度组合使用一个字符串吗?@ruohola我在'config.py'中有一个'config'字典对象。用户可以选择从“命令行”覆盖此值,例如(例如
    python run.py env=dev user.name.last=John
    )@JaiK您是否考虑过您的
    config
    字典可以采用更简单的格式?@ruohola有一段时间,我想将它们作为一个单元进行分组,例如,“数据库”的配置被分组为
    db:{'HOST'='X','PORT':8080,'USERNAME':'XXX','PASSWORD':'YYY'}
    ,目标输出被分组为
    dest:{'DIR\u PATH':'/output','FILE\u EXT':'csv}
    etcIs使用此临时文件有任何特殊原因。var
    current=a
    ,由于没有此分配,上述代码也在工作。我的意思是,直接使用“a”而不是“current”。@jai没有赋值a将变成“{'first':'Micheal','last':'henry'}”
    def get_keys_value(string):
        keys, value = string.split("=")
        return keys, value
    
    def get_exec_string(dict_name, keys):
        exec_string = dict_name
        for key in keys.split("."):
            exec_string = exec_string + "[" + key + "]"
        exec_string = exec_string + "=" + "value"
        return exec_string
    
    str_key_1 = "'user'.'username'=john"
    str_key_2 = "'user'.'name'.'last'=henry"
    str_key_list = [str_key_1, str_key_2]
    
    for str_key in str_key_list:
        keys, value = get_keys_value(str_key) # split into key-string and value
        exec_string = get_exec_string("a", keys) # extract keys from key-string 
        exec(exec_string)
    
    print(a)
    # prints {'user': {'email': 'micheal@domain.com', 'name': {'last': 'henry', 'first': 'Micheal'}, 'username': 'john'}}
    
    str_key_1 = 'user.username=john'
    str_key_2 = 'user.name.last=henry'
    
    a = {
        'user': {
            'username': 'mic_jack',    
            'name': {
                'first': 'Micheal',
                'last': 'Jackson'
            },
            'email': 'micheal@domain.com',
    
            #...
            #... Infinite level of another nested dict
        }     
    }
    
    def MutateDict(key):
        strkey, strval = key.split('=')[0], key.split('=')[1]
        strkeys = strkey.split('.')
        print("strkeys = " ,strkeys)
        target = a
        k = ""
        for k in strkeys:
            print(target.keys())
            if k in target.keys():
                prevTarget = target
                target = target[k]
            else:
                print ("Invalid key specified")
                return
        prevTarget[k] = strval
    
    
    MutateDict(str_key_1)
    
    print(a)
    
    MutateDict(str_key_2)
    
    print(a)