Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting string to ordered dictionary?

I have a string which basically contains a bunch of JSON formatted text that I'd ultimately like to export to Excel in "pretty print" format with the proper indentations for nesting, etc.

It's imperative that the original order of key/values is retained for readability purposes. My thought process to accomplish what I want is to

a) use something like eval to convert the string to a dictionary and b) use OrderedDict from the collections library to keep the order intact.

However I'm not getting the expected result:

In [21]: json_string = str({"id":"0","last_modified":"undefined"})
In [22]: OrderedDict(eval(json_string))
Out[23]: OrderedDict([('last_modified', 'undefined'), ('id', '0')])

I also haven't quite figured out yet how I'm going to write the output to excel in pretty print format, but I'd hope that'd be the comparatively easy part!

like image 835
ChrisArmstrong Avatar asked May 20 '13 00:05

ChrisArmstrong


People also ask

How do I convert a string to a dictionary?

Method 1: Splitting a string to generate key:value pair of the dictionary In this approach, the given string will be analysed and with the use of split() method, the string will be split in such a way that it generates the key:value pair for the creation of a dictionary.

Can Python dictionary be ordered?

As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered. When we say that dictionaries are ordered, it means that the items have a defined order, and that order will not change.

How do you convert a string to a list in Python?

To do this we use the split() method in string. The split method is used to split the strings and store them in the list. The built-in method returns a list of the words in the string, using the “delimiter” as the delimiter string.

How do you convert a variable to a dictionary in Python?

Using zip and dictThe dict() can be used to take input parameters and convert them to a dictionary. We also use the zip function to group the keys and values together which finally become the key value pair in the dictionary.


2 Answers

You can use the object_pairs_hook argument to JSONDecoder to change the decoded dictionaries to OrderedDict:

import collections
import json

decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)

json_string = '{"id":"0","last_modified":"undefined"}'
print decoder.decode(json_string)
json_string = '{"last_modified":"undefined","id":"0"}'
print decoder.decode(json_string)

This prints:

OrderedDict([(u'id', u'0'), (u'last_modified', u'undefined')])
OrderedDict([(u'last_modified', u'undefined'), (u'id', u'0')])
like image 60
jterrace Avatar answered Oct 04 '22 13:10

jterrace


First, you should consider using json (or even ast.literal_eval) instead of eval.

Secondly, this won't work because the minute you turn it into a regular dictionary, all order is lost. You'll need to parse the "json" yourself if you want to put the information into an OrderedDict.

Fortunately, this isn't quite as hard as you might think if you use the ast module. Here I'm assuming that the dictionary only contains strings but it shouldn't be too hard to modify for other purposes.

s = '{"id":"0","last_modified":"undefined"}'
import ast
from collections import OrderedDict
class DictParser(ast.NodeVisitor):
    def visit_Dict(self,node):
        keys,values = node.keys,node.values
        keys = [n.s for n in node.keys]
        values = [n.s for n in node.values]
        self.od = OrderedDict(zip(keys,values))

dp = DictParser()
dp.visit(ast.parse(s))
ordered_dict = dp.od
print ordered_dict
like image 21
mgilson Avatar answered Oct 04 '22 13:10

mgilson