Replace values in dict if value of another key within a nested dict is found in value

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-10 14:23:01

问题


I have the following nested 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'}
           }

I want to replace any $variableX specified for a dict key with the dict value from another key if the key from the other dict value if found in the value of the original dict key. See example output below:

{'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
       }  

Does anyone have any suggestions?


回答1:


You could do replacement by recursively walking through the dict and using the re library to do the replacements

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 = []

Edit:

I added a reprocessing step to handle the cases where the references are chained and require multiple passes through some keys in the dictionary to fully process them.




回答2:


Not a very Pythonic solution, but, does the trick:

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)

Output:

{'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'}}



回答3:


You can use a dictionary comprehension:

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()}

Output:

{'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'}}


来源:https://stackoverflow.com/questions/49435546/replace-values-in-dict-if-value-of-another-key-within-a-nested-dict-is-found-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!