1

I have a very long string, that looks like a dictionary, but where many of the keys have been replaced by variables that are undefined, e.g.:

dict_1_str = '{a: "date", b: 7, c: {d: 5, e: "Hello There!"}}'

In an actual dictionary, I have the variable names and values.

dict_2 = {"a": 1, "b": 2, "c": 3, "d": "General Kenobi!", "e": 5}

I want to update the keys in the top dictionary with the values in the bottom dictionary. I thought I could create a list of dict_2's keys and a list of dict_2's values, and then use exec() to evaluate the lists as equal, and so set all the variables in one go — but I cannot get it to work, and I would rather avoid exec() if I can.

I tried to use regex, but many of string values in dict_1_str contain the names of the keys/variables. Is there some elegant way of doing this?

1
  • 4
    I don't think I understand. For the input you've shown, what is the desired output? Commented Feb 26, 2021 at 6:55

3 Answers 3

1

It would be slightly less unsafe than using exec(), but you can use eval() and pass it a globals dictionary argument that would prevent any Python built-ins from being used by the expression being passed to evaluate. (Your dict_2 would be the locals argument.)

import json

dict_1_str = '{a: "date", b: 7, c: {d: 5, e: "Hello There!"}}'
dict_2 = {"a": 1, "b": 2, "c": 3, "d": "General Kenobi!", "e": 5}

result = eval(dict_1_str, {'__builtins__': None}, dict_2)
print(json.dumps(result))

Output:

{"1": "date", "2": 7, "3": {"General Kenobi!": 5, "5": "Hello There!"}}
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah this worked nicely, thanks. I was close, just didn't quite understand how to use the locals argument .
Note that using the locals argument isn't a requirement. eval(dict_1_str, dict({'__builtins__': None}, **dict_2)) would also work fine but is a little harder to understand (as well as write).
0

Does this module demjson helps?

pip install demjson

You can try with below codes for your reference.

import demjson

dict_1_str = '{a: "date", b: 7, c: {d: 5, e: "Hello There!"}}'
dict_2 = {"a": 1, "b": 2, "c": 3, "d": "General Kenobi!", "e": 5}

s = demjson.decode(dict_1_str)
s.update(dict_2)
print(s)
# {'a': 1, 'b': 2, 'c': 3, 'd': 'General Kenobi!', 'e': 5}

r = demjson.encode(s)
print(r)
# {"a":1,"b":2,"c":3,"d":"General Kenobi!","e":5}

1 Comment

I had a go at this. it turns out some of the values in the dict1_str are also unquoted, and I think this method failed because of that, which was not in the original question. But I think it does work when only the keys need to be replaced. Thanks
0
import json 

# first I added quotes to surround property names in the string
dict_1_str = '{"a": "date", "b": 7, "c": {"d": 5, "e": "Hello There!"}}'
dict_2 = {"a": 1, "b": 2, "c": 3, "d": "General Kenobi!", "e": 5}

# This will convert the string to a dict
dict_1 = json.loads(dict_1_str)

# Here is a solution to merge two dict
dict_3 = {**dict_1, **dict_2}

Here you can read more on How do I merge two dictionaries in a single expression in Python (taking union of dictionaries)?

1 Comment

The problem is in your first comment, the current str does not have quotes around the keys.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.