How to check if a string contains a dictionary
<p>I want to recursively parse all values in a dict that are strings with <code>ast.literal_eval(value)</code> but not do that eval if the string doesn't contain a dict. I want this, because I have a string in a dict that is a dict in itself and I would like the value to be a dict. Best to give an example</p>

<pre><code>my_dict = {'a': 42, 'b': "my_string", 'c': "{'d': 33, 'e': 'another string'}"}
</code></pre>

<p>Now I don't want a do to <code>ast.literal_eval(my_dict['c'])</code> I want a generic solution where I can do <code>convert_to_dict(my_dict)</code></p>

<p>I wanted to write my own method, but I don't know how to check if a string contains a dict, and then ast.literal_eval will fail, hence the question.</p>

<p>If you need to handle nested <code>str</code> defining <code>dict</code>, <a href="https://docs.python.org/3/library/json.html#json.loads" rel="nofollow"><code>json.loads</code> with an <code>object_hook</code></a> might work for you:</p>

<pre><code>import json

def convert_subdicts(d):
    for k, v in d.items():
        try:
            # Try to decode a dict
            newv = json.loads(v, object_hook=convert_subdicts)
        except Exception:
            continue
        else:
            if isinstance(newv, dict):
                d[k] = newv  # Replace with decoded dict
    return d

origdict = {'a': 42, 'b': "my_string", 'c': "{'d': 33, 'e': 'another string'}"}
newdict = convert_subdicts(origdict.copy())  # Omit .copy() if mutating origdict okay
</code></pre>

<p>That should recursively handle the case where the contained <code>dict</code>s might contain <code>str</code>s values that define subdicts. If you don't need to handle that case, you can omit the use of the <code>object_hook</code>, or replace <code>json.loads</code> entirely with <code>ast.literal_eval</code>.</p>

python string python-3.x dictionary recursion