【问题标题】:Save dict of key and list of dict inside key to JSON where dictionary is stored by line将键的字典和键内的字典列表保存到按行存储字典的 JSON
【发布时间】:2019-10-10 17:03:20
【问题描述】:

我有一个与this previous question 类似的问题。但是,我的字典具有如下结构

data_dict = {
  'refresh_count': 1,
  'fetch_date': '10-10-2019',
  'modified_date': '',
  'data': [
      {'date': '10-10-2019', 'title': 'Hello1'}, 
      {'date': '11-10-2019', 'title': 'Hello2'}
  ]
}

我想将它存储在 JSON 中,以便我的数据仍然存储在每行一个字典中。比如:

{
  'refresh_count': 1,
  'fetch_date': '10-10-2019',
  'modified_date': '',
  'data': [
      {'date': '10-10-2019', 'title': 'Hello1'}, 
      {'date': '11-10-2019', 'title': 'Hello2'}
  ]
}

我无法仅使用json.dumps(或dump)或以前的解决方案来实现它。

json.dumps(data_dict, indent=2)

>> {
  "refresh_count": 1,
  "fetch_date": "10-10-2019",
  "modified_date": "",
  "data": [
    {
      "date": "10-10-2019",
      "title": "Hello1"
    },
    {
      "date": "11-10-2019",
      "title": "Hello2"
    }
  ]

}

【问题讨论】:

  • 你能发布json.dumps的输出吗?

标签: python json python-3.x dictionary


【解决方案1】:

这是一个 hack,但您可以实现一个自定义 JSON 编码器,它会执行您想要的操作(请参阅 Custom JSON Encoder in Python With Precomputed Literal JSON)。对于您不想缩进的任何对象,用NoIndent 类包装它。自定义 JSON 编码器将在 default() 方法中查找此类型并返回唯一字符串 (__N__) 并将未缩进的 JSON 存储在 self._literal 中。稍后,在对 encode() 的调用中,这些唯一的字符串被替换为未缩进的 JSON。

请注意,您需要选择一种不可能出现在编码数据中的字符串格式,以避免无意中替换某些内容。

import json


class NoIndent:

    def __init__(self, o):
        self.o = o


class MyEncoder(json.JSONEncoder):

    def __init__(self, *args, **kwargs):
        super(MyEncoder, self).__init__(*args, **kwargs)
        self._literal = []

    def default(self, o):
        if isinstance(o, NoIndent):
            i = len(self._literal)
            self._literal.append(json.dumps(o.o))
            return '__%d__' % i
        else:
            return super(MyEncoder, self).default(o)

    def encode(self, o):
        s = super(MyEncoder, self).encode(o)
        for i, literal in enumerate(self._literal):
            s = s.replace('"__%d__"' % i, literal)
        return s


data_dict = {
  'refresh_count': 1,
  'fetch_date': '10-10-2019',
  'modified_date': '',
  'data': [
      NoIndent({'date': '10-10-2019', 'title': 'Hello1'}),
      NoIndent({'date': '11-10-2019', 'title': 'Hello2'}),
  ]
}

s = json.dumps(data_dict, indent=2, cls=MyEncoder)
print(s)

super(MyEncoder, self).encode(o)返回的中间表示:

{
  "fetch_date": "10-10-2019", 
  "refresh_count": 1, 
  "data": [
    "__0__", 
    "__1__"
  ], 
  "modified_date": ""
}

最终输出:

{
  "fetch_date": "10-10-2019", 
  "refresh_count": 1, 
  "data": [
    {"date": "10-10-2019", "title": "Hello1"}, 
    {"date": "11-10-2019", "title": "Hello2"}
  ], 
  "modified_date": ""
}

【讨论】:

  • 这看起来很棒!我会尽快尝试并接受解决方案!
  • 你也可以试试 Python 3 吗?我实际上无法在 Python 3 中重现输出。谢谢!
  • 如果您正在寻找问题,您应该标记您的问题 python-3.x。它适用于我的机器上的 2.7.15 和 3.6.8(修复 print 之后)。
  • 我测试过,效果很好。接受答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多