3

I have python's str dictionary representations in a database as varchars, and I want to retrieve the original python dictionaries

How to have a dictionary again, based in the str representation of a dictionay?

Example

>>> dic = {u'key-a':u'val-a', "key-b":"val-b"}
>>> dicstr = str(dic)
>>> dicstr
"{'key-b': 'val-b', u'key-a': u'val-a'}"

In the example would be turning dicstr back into a usable python dictionary.

Community
  • 1
  • 1
jperelli
  • 6,988
  • 5
  • 50
  • 85
  • BTW are they Python dictionaries or JSON objects? Easy to confuse the two :) – Kos Oct 31 '12 at 18:44
  • Python dictionaries. I think json doesn't allow the `u'sth'` syntax (looking at the `u` from unicode) – jperelli Oct 31 '12 at 18:46
  • Nope, but I cannot see your real data, can I? JSON ends up considerably more often in databases than Python `repr`-encoded objects, so I thought I'd point that out just in case. – Kos Nov 01 '12 at 00:28
  • 1
    If that's your database, you might want to consider using the `pickle` module instead of `repr` (unless you want the data human-readable too). – Kos Nov 01 '12 at 00:29

3 Answers3

12

Use ast.literal_eval() and for such cases prefer repr() over str(), as str() doesn't guarantee that the string can be converted back to useful object.

In [7]: import ast

In [10]: dic = {u'key-a':u'val-a', "key-b":"val-b"}

In [11]: strs = repr(dic)

In [12]: strs
Out[12]: "{'key-b': 'val-b', u'key-a': u'val-a'}"

In [13]: ast.literal_eval(strs)
Out[13]: {u'key-a': u'val-a', 'key-b': 'val-b'}
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Does repr guarantee the backconversion? With numpy array in the dict it doesnt work. – lalala Oct 26 '19 at 09:32
  • Does this not seem like an unsafe answer to anyone else?? Don't eval strings use the `json` package. – johnsimer Jan 26 '21 at 21:17
  • @johnsimer Answer is using [`ast.literal_eval()`](https://docs.python.org/3/library/ast.html#ast.literal_eval) not `eval()` and OPs string is not JSON. – Ashwini Chaudhary Jan 26 '21 at 21:34
2

You can use eval() or ast.literal_eval(). Most repr() strings can be evaluated back into the original object:

>>> import ast
>>> ast.literal_eval("{'key-b': 'val-b', u'key-a': u'val-a'}")
{'key-b': 'val-b', u'key-a': u'val-a'}
Blender
  • 289,723
  • 53
  • 439
  • 496
1

ast.literal_eval could be the way to do it for simple dicts, BUT you should probably rethink your design and NOT save such text in database at first place. e.g.

import collections
d = {'a':1, 'b': collections.defaultdict()}

import ast
print ast.literal_eval(repr(d))

This will not work and throw ValueError('malformed string') basically you won't be convert back dict if it contains any non basic types.

Better way is to dump dict using pickle or json or something like that e.g.

import collections
d = {'a':1, 'b': collections.defaultdict()}

import json
print json.loads(json.dumps(d))

Summary: serialize using repr, deserialize using ast.literal_eval is BAD, serialize using json.dumps and deserialize using json.loads is GOOD

Anurag Uniyal
  • 85,954
  • 40
  • 175
  • 219