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!
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.
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.
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.
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.
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')])
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With