问题
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