In the following dictionary, a user can refer to a key as a variable for defining another value:
d = {'a_key': 'a_value', 'b_key': '[ a_key ]+1/[a_key]'}
I have to replace these references by the corresponding values, in order to obtain this desired output:
d = {'a_key': 'a_value', 'b_key': 'a_value+1/a_value'}
The references are delimited by squared brackets in order to prevent unwanted replacements (it's a safer version than the simple str replacement asked at Replace key references by corresponding values in dict values). Thus I use a regex for performing the replacement:
from re import search, sub
d = {'a_key': 'a_value', 'b_key': '[ a_key ]+1/[a_key]'}
for k in d.keys():
parameter = search(r"\[\s*(\w+)\s*\]", d[k])
if parameter is not None and parameter.group(1) in d.keys():
print("target: "+parameter.group())
print("to be replaced by: "+d[parameter.group(1)])
d[k] = sub(parameter.group(), d[parameter.group(1)], d[k])
print(d)
The output is:
target: [ a_key ]
to be replaced by: a_value
{'a_key': 'a_value', 'b_key': '[a_valuea_valuea_valuea_valuea_valuea_valuea_value]+1/[a_valuea_valuea_valuea_valuea_value]'}
Despite the target has been acquired and the replacement group is correct, the squared brackets are still there and, between them, each single character has been replaced by the replacement group. What's wrong with my regex and how to get the desired outpout ?
EDIT:
Thanks to Joshua Varghese's answer, I have to precise that there might not only be key references between squared brackets. For instance:
d = {'a_key': 'a_value', 'b_key': '[ a_key ]+1/[a_key]+[another_thing ]'}
Here I don't want [another_thing]
to be replaced. By trying with this example, I found that not all characters are replaced. However among the replaced ones, there are white spaces and any character contained in the key. [another_thing]
will become [a_valuenotha_valuera_valuethinga_value]
EDIT2:
Thanks to WeavingBird1917's comment, I will try to use something like the code below instead of setting the code in a for _ in d:
loop. However, since dict are unordered, I don't know how to complete the recursive function. Any help appreciated.
from re import search, sub
d = {'a_key': '[c_key]', 'b_key': '1', 'c_key': '[b_key] + [e_key]*[another_thing ]', 'd_key': '[b_key]', 'e_key': '[b_key]'}
def rec(z):
parameter = search(r"\[\s*(\w+)\s*\]", d[z])
if parameter is not None and parameter.group(1) in d.keys():
rec(parameter.group(1))
else:
print("+1")
for k in d:
d[k] = sub(r"\[\s*(\w+)\s*\]", lambda match: "(" + d[match.group(1)] + ")" if match.group(1) in d else match.group(), d[k])
# need to go to the next key or to break if no other, but dict are unordered
rec(list(d.keys())[0])
print(d)