Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 若在value中找到嵌套dict中另一个键的值,则替换dict中的值_Python_Dictionary - Fatal编程技术网

Python 若在value中找到嵌套dict中另一个键的值,则替换dict中的值

Python 若在value中找到嵌套dict中另一个键的值,则替换dict中的值,python,dictionary,Python,Dictionary,我有以下嵌套的dict: ex_dict = {'path1': {'$variable1': '2018-01-01', '$variable2': '2020-01-01', '$variable3': '$variable1', '$variable4': '$variable3'}, 'path2': {'$variable1'

我有以下嵌套的dict:

 ex_dict = {'path1':
             {'$variable1': '2018-01-01',
              '$variable2': '2020-01-01',
              '$variable3': '$variable1',
              '$variable4': '$variable3'},
            'path2':
             {'$variable1': '2018-01-01',
              '$variable2': '2020-01-01',
              '$variable3': '$variable1',
              '$variable4': '$variable1 + $variable2'}
           }
如果在原始dict键的值中找到另一个dict值的键如果,我想用另一个键的dict值替换为dict键指定的任何$variableX。请参见下面的示例输出:

{'path1':
         {'$variable1': '2018-01-01',
          '$variable2': '2020-01-01',
          '$variable3': '2018-01-01',  # Substituted with value from key:variable1
          '$variable4': '2018-01-01'}, # Substituted with value from key:variable3 (after variable3 was substituted with variable1)    
 'path2':
         {'$variable1': '2018-01-01',
          '$variable2': '2020-01-01',
          '$variable3': '2018-01-01',  # Substituted with value from key:variable1
          '$variable4': '2018-01-01 + 2020-01-01'} # Substituted with value from key:variable3 (after variable3 was substituted with variable1) and key:variable2
       }  

有人有什么建议吗

您可以通过递归遍历dict并使用
re
库来进行替换

import re

def process_dict(d):
    reprocess = []
    keys = d.keys()
    while keys:
        for k in keys:
            v = d[k]
            if isinstance(v, dict):
                process_dict(v)
            elif '$' in v:
                d[k] = re.sub(r'\$\w+', lambda m: d[m.group(0)] if m.group(0) in d else m.group(0), v)
                if '$' in d[k] and d[k] != v:
                    reprocess.append(k)
        keys = reprocess
        reprocess = []
编辑:

我添加了一个重新处理步骤来处理引用被链接的情况,并且需要多次通过字典中的一些键来完全处理它们。

这不是一个非常Pythonic的解决方案,但是,它的技巧是:

ex_dict = {'path1':
               {'$variable1': '2018-01-01',
                '$variable2': '2020-01-01',
                '$variable3': '$variable1',
                '$variable4': '$variable3'},
           'path2':
               {'$variable1': '2018-01-01',
                '$variable2': '2020-01-01',
                '$variable3': '$variable1',
                '$variable4': '$variable1 + $variable2'}
           }

for path, d in ex_dict.items():
    for k, v in d.items():
        if v.startswith('$variable'):
            try:
                if '+' in v:
                    ex_dict[path][k] = ' + '.join(ex_dict[path][x.strip()] for x in v.split('+'))
                else:
                    ex_dict[path][k] = ex_dict[path][v]
            except KeyError:
                pass

pprint(ex_dict)
输出:

{'path1': {'$variable1': '2018-01-01',
           '$variable2': '2020-01-01',
           '$variable3': '2018-01-01',
           '$variable4': '2018-01-01'},
 'path2': {'$variable1': '2018-01-01',
           '$variable2': '2020-01-01',
           '$variable3': '2018-01-01',
           '$variable4': '2018-01-01 + 2020-01-01'}}
{'path2': {'$variable4': '2018-01-01 + 2020-01-01', '$variable2': '2020-01-01', '$variable3': '2018-01-01', '$variable1': '2018-01-01'}, 'path1': {'$variable4': '$variable1', '$variable2': '2020-01-01', '$variable3': '2018-01-01', '$variable1': '2018-01-01'}}

您可以使用字典理解:

import re
dict = {'path1':
     {'$variable1': '2018-01-01',
      '$variable2': '2020-01-01',
      '$variable3': '$variable1',
      '$variable4': '$variable3'},
    'path2':
     {'$variable1': '2018-01-01',
      '$variable2': '2020-01-01',
      '$variable3': '$variable1',
      '$variable4': '$variable1 + $variable2'}
   }

final_data = {a:{c:d if re.findall('\d+-\d+-\d+', d) else \
re.sub('\$\w+', '{}', d).format(*[b[i] for i in re.findall('\$\w+', d)]) \
 for c, d in b.items()} for a, b in dict.items()}
输出:

{'path1': {'$variable1': '2018-01-01',
           '$variable2': '2020-01-01',
           '$variable3': '2018-01-01',
           '$variable4': '2018-01-01'},
 'path2': {'$variable1': '2018-01-01',
           '$variable2': '2020-01-01',
           '$variable3': '2018-01-01',
           '$variable4': '2018-01-01 + 2020-01-01'}}
{'path2': {'$variable4': '2018-01-01 + 2020-01-01', '$variable2': '2020-01-01', '$variable3': '2018-01-01', '$variable1': '2018-01-01'}, 'path1': {'$variable4': '$variable1', '$variable2': '2020-01-01', '$variable3': '2018-01-01', '$variable1': '2018-01-01'}}

你不应该给字典命名,因为这是一个内置的名字。