Python: 'unicode' object has no attribute 'iteritems'
Question: In my app using Python 2.6.9 I have this incoming JSON as a unicode string:

    
    
    {"devices": "{1540702298: u\"{'on': u'True', 'group': '2', 'time': u'2015-06-04 16:37:52', 'value': u'74.1', 'lastChange': u'2015-06-05 09:28:10'}\"}"}
    

I have tried in various ways to parse it but I still get the same error...

For example:

    
    
    a = unicode({"devices": "{1540702298: u\"{'on': u'True', 'group': '2', 'energyAccumBaseTime': u'2015-06-04 16:37:52', 'sensorValueRaw': u'74.1', 'lastChange': u'2015-06-05 09:28:10', 'energyAccumTotal': u'1.3', 'sensorValueUi': u'74.1'}\"}"})
    
    b = json.loads(a)
    
    print b['devices'] # all good I get the contents...
    

but when I do...

    
    
    for k, v in b['devices'].iteritems():
    
    print k
    

I get the error:

> 'unicode' object has no attribute 'iteritems'

How can I parse this incoming JSON in full?


Answer: The outer object may be JSON, but it contains a string that itself is a Python
dictionary literal, containing Unicode literals as values.

Someone did this:

    
    
    python_dictionary = {}
    python_dictionary[integer_key] = str(another_dictionary)
    outer_object {"devices": str(python_dictionary)}
    

before encoding the `outer_object` to JSON. Each value in that dictionary is
itself another string representing a Python dictionary, and those dictionaries
contain more strings representing dictionaries, like so many [Matryoshka
dolls](http://en.wikipedia.org/wiki/Matryoshka_doll).

You can use the [`ast.literal_eval()`
function](https://docs.python.org/2/library/ast.html#ast.literal_eval) to turn
that back into Python objects:

    
    
    import ast
    import json
    
    yourobject = json.loads(jsondata)
    dictionary = ast.literal_eval(yourobject['devices'])
    for key, nested in dictionary.iteritems():
        nested = ast.literal_eval(nested)
        print key, nested
    

but you should really fix whatever produced the string to avoid storing the
nested dictionary as a string. Note that the keys in that nested dictionary
are integers; those would have to be converted to strings to work in JSON.

Demo:

    
    
    >>> import json
    >>> import ast
    >>> jsondata = r'''{"devices": "{1540702298: u\"{'on': u'True', 'group': '2', 'time': u'2015-06-04 16:37:52', 'value': u'74.1', 'lastChange': u'2015-06-05 09:28:10'}\"}"}'''
    >>> yourobject = json.loads(jsondata)
    >>> type(yourobject['devices'])
    <type 'unicode'>
    >>> ast.literal_eval(yourobject['devices'])
    {1540702298: u"{'on': u'True', 'group': '2', 'time': u'2015-06-04 16:37:52', 'value': u'74.1', 'lastChange': u'2015-06-05 09:28:10'}"}
    >>> dictionary = ast.literal_eval(yourobject['devices'])
    >>> dictionary[1540702298]
    u"{'on': u'True', 'group': '2', 'time': u'2015-06-04 16:37:52', 'value': u'74.1', 'lastChange': u'2015-06-05 09:28:10'}"
    >>> type(dictionary[1540702298])
    <type 'unicode'>
    
    >>> for key, nested in dictionary.iteritems():
    ...     nested = ast.literal_eval(nested)
    ...     print key, nested
    ... 
    1540702298 {'on': u'True', 'lastChange': u'2015-06-05 09:28:10', 'group': '2', 'value': u'74.1', 'time': u'2015-06-04 16:37:52'}
    

