How do I serialize a Python dictionary into a string, and then back to a dictionary?

前端 未结 8 988
我在风中等你
我在风中等你 2020-11-29 20:46

How do I serialize a Python dictionary into a string, and then back to a dictionary? The dictionary will have lists and other dictionaries inside it.

相关标签:
8条回答
  • If you are trying to only serialize then pprint may also be a good option. It requires the object to be serialized and a file stream.

    Here's some code:

    from pprint import pprint
    my_dict = {1:'a',2:'b'}
    with open('test_results.txt','wb') as f:
        pprint(my_dict,f)
    

    I am not sure if we can deserialize easily. I was using json to serialize and deserialze earlier which works correctly in most cases.

    f.write(json.dumps(my_dict, sort_keys = True, indent = 2, ensure_ascii=True))
    

    However, in one particular case, there were some errors writing non-unicode data to json.

    0 讨论(0)
  • 2020-11-29 21:24

    Use Python's json module, or simplejson if you don't have python 2.6 or higher.

    0 讨论(0)
  • 2020-11-29 21:24

    One thing json cannot do is dict indexed with numerals. The following snippet

    import json
    dictionary = dict({0:0, 1:5, 2:10})
    serialized = json.dumps(dictionary)
    unpacked   = json.loads(serialized)
    print(unpacked[0])
    

    will throw

    KeyError: 0
    

    Because keys are converted to strings. cPickle preserves the numeric type and the unpacked dict can be used right away.

    0 讨论(0)
  • 2020-11-29 21:28

    If you fully trust the string and don't care about python injection attacks then this is very simple solution:

    d = { 'method' : "eval", 'safe' : False, 'guarantees' : None }
    s = str(d)
    d2 = eval(s)
    for k in d2:
        print k+"="+d2[k]
    

    If you're more safety conscious then ast.literal_eval is a better bet.

    0 讨论(0)
  • 2020-11-29 21:32

    Pickle is great but I think it's worth mentioning literal_eval from the ast module for an even lighter weight solution if you're only serializing basic python types. It's basically a "safe" version of the notorious eval function that only allows evaluation of basic python types as opposed to any valid python code.

    Example:

    >>> d = {}
    >>> d[0] = range(10)
    >>> d['1'] = {}
    >>> d['1'][0] = range(10)
    >>> d['1'][1] = 'hello'
    >>> data_string = str(d)
    >>> print data_string
    {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], '1': {0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 1: 'hello'}}
    
    >>> from ast import literal_eval
    >>> d == literal_eval(data_string)
    True
    

    One benefit is that the serialized data is just python code, so it's very human friendly. Compare it to what you would get with pickle.dumps:

    >>> import pickle
    >>> print pickle.dumps(d)
    (dp0
    I0
    (lp1
    I0
    aI1
    aI2
    aI3
    aI4
    aI5
    aI6
    aI7
    aI8
    aI9
    asS'1'
    p2
    (dp3
    I0
    (lp4
    I0
    aI1
    aI2
    aI3
    aI4
    aI5
    aI6
    aI7
    aI8
    aI9
    asI1
    S'hello'
    p5
    ss.
    

    The downside is that as soon as the the data includes a type that is not supported by literal_ast you'll have to transition to something else like pickling.

    0 讨论(0)
  • 2020-11-29 21:32

    While not strictly serialization, json may be reasonable approach here. That will handled nested dicts and lists, and data as long as your data is "simple": strings, and basic numeric types.

    0 讨论(0)
提交回复
热议问题