将字符串转换为有序字典?

6
我有一个字符串,其中包含一堆以JSON格式编写的文本,最终希望以“漂亮打印”格式将其导出到Excel中,并对嵌套进行适当缩进等。为了阅读方便,必须保留键/值的原始顺序。我考虑实现我的想法:

a) 使用类似eval的方法将字符串转换为字典, b) 使用collections库中的OrderedDict来保持顺序不变。

但是我没有得到期望的结果:

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

我还没有完全想清楚如何以漂亮的打印格式将输出写入Excel,但我希望这应该是相对简单的部分!

3个回答

20
你可以使用object_pairs_hook参数将JSONDecoder解码的字典更改为OrderedDict,参考文档:JSONDecoder
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)

这将打印:

OrderedDict([(u'id', u'0'), (u'last_modified', u'undefined')])
OrderedDict([(u'last_modified', u'undefined'), (u'id', u'0')])

呵呵,总有不止一种方法来解决问题 :) - jterrace
1
但有些方法比其他方法更干净...我仍在考虑删除我的。它至少是解析Python语法的一个很好的例子,但我不知道这是否可以证明留下它,因为这种方法要好得多... - mgilson
@mgilson 肯定也要在这里留下来。 - jamylak
@mgilson:算了吧!抽象语法树还没被完全探索。 - dawg

7
首先,您应该考虑使用json(甚至ast.literal_eval)而不是eval
其次,这样做行不通,因为一旦将其转换为常规字典,所有顺序都会丢失。如果想要将信息放入OrderedDict中,就需要自己解析“json”。
幸运的是,如果使用ast模块,这并不像你想象的那么难。在这里,我假设字典仅包含字符串,但对于其他用途进行修改也不应该太难。
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

嗯,我想这可能是情况。也许最好使用正则表达式重新格式化JSON字符串(例如用换行符替换逗号等)。 - ChrisArmstrong
我确实喜欢ast。几个月前我才弄明白如何使用它,所以每当涉及解析类似Python的字符串时,它就是我首先考虑的东西。 - mgilson
@mgilson,虽然我选择了上面的答案,但这确实很酷——感谢您的贡献 :) - ChrisArmstrong
@ChrisArmstrong -- 我很高兴你选择了另一个答案,因为这才是正确的做法。如果你接受了我的答案,我就不得不删除它 :). 我想我足够开心,把它留作为一些使用ast的有趣事例,只要清楚另一个答案更适合解决这个特定的问题。 - mgilson

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接