【问题标题】:How to save a dictionary into a file, keeping nice format?如何将字典保存到文件中,保持良好的格式?
【发布时间】:2016-07-05 21:55:01
【问题描述】:

如果我有这样的字典:

{
  "cats": {
           "sphinx": 3,
           "british": 2
          },
  "dogs": {}
}

并尝试将其保存到文本文件中,我得到如下内容:

{"cats": {"sphinx": 3}, {"british": 2}, "dogs": {}}

我怎样才能以漂亮的格式保存字典,以便人眼阅读?

【问题讨论】:

    标签: python file dictionary save output


    【解决方案1】:

    您可以导入 json 并指定缩进级别:

    import json
    
    d = {
      "cats": {
               "sphinx": 3,
               "british": 2
              },
      "dogs": {}
    }
    
    j = json.dumps(d, indent=4)
    print(j)
    {
        "cats": {
            "sphinx": 3, 
            "british": 2
        }, 
        "dogs": {}
    }
    

    请注意,这是一个字符串,但是:

    >>> j
    '{\n    "cats": {\n        "sphinx": 3, \n        "british": 2\n    }, \n    "dogs": {}\n}'
    

    【讨论】:

      【解决方案2】:

      您可以为此使用pprint

      import pprint
      pprint.pformat(thedict)
      

      【讨论】:

      • 这对我不起作用。它在一行中显示,就像 OP 已经拥有的一样。
      • @zondo 我用这个:file.write(pprint.pformat(my_dict))
      【解决方案3】:

      如果你想以更标准的格式保存,你也可以使用例如yaml文件(以及相关的python包http://pyyaml.org/wiki/PyYAMLDocumentation),代码如下:

      import yaml
      dictionary = {"cats": {"sphinx": 3}, {"british": 2}, "dogs": {}}
      with open('dictionary_file.yml', 'w') as yaml_file:
           yaml.dump(dictionary, stream=yaml_file, default_flow_style=False)
      

      dump 创建一个 yaml 格式的字符串以写入文件。请注意,可以指定流并将内容立即写入文件。如果由于某种原因需要在写入文件之前获取字符串,请不要指定它并在对文件使用write函数后写入。 另请注意,参数 default_flow_style 允许使用更好的格式;在示例中,文件看起来:

      cats:
        british: 2
        sphinx: 3
      dogs: {}
      

      再次加载字典中的 yaml 文件:

      import yaml
      with open('dictionary_file.yml', 'r') as yaml_file:
          dictionary = yaml.load(yaml_file)
      

      【讨论】:

      • 我喜欢 YAML 格式,但是你使用它的方式,你让 yaml 库将内容写入一个假文件,然后从那个假文件中检索内容,然后将其写入一个真实文件.为什么不直接写到真实文件中,防止这种低效呢?
      • 我没有使用假文件。答案中的第一个代码写入实际文件,第二个代码从实际文件中读取。 python 中提供的 with 语句允许打开名为 dictionary_file.yml 的文件,并且可以使用变量 yaml_file 访问文件对象,并且在 with 块的末尾将其关闭,而无需调用 close() 函数文件。检查docs.python.org/2/tutorial/inputoutput.html 的第 7.2.1 节。
      • 你似乎不知道 PyYAML 是如何工作的。如果您没有指定 stream 参数,它首先将整个转储写入内存中的假文件 (StringIO)。
      • 哦,对不起,我误解了你的意思。你是对的,可以直接指定写入整个转储的流。对于不了解 PyYAML 的人,我只是想将转储和写入分离,以便以更清晰的方式显示正在发生的事情以及可以获得字符串。无论如何,如果每个人都清楚这一点,我会相应地修改答案。
      【解决方案4】:

      您可以使用 Python Object Notation 模块转储它(pon:免责声明我是该模块的作者)

      from pon import PON, loads
      
      data = {
          "cats": {
              "sphinx": 3,
              "british": 2
              },
          "dogs": {}
      }
      
      pon = PON(obj=data)
      pon.dump()
      

      给出:

      dict(
          cats=dict(
              sphinx=3,
              british=2,
          ),
          dogs=dict(    ),
      )
      

      这又是正确的 Python,但使用 dict 交换键所需的引号字符串。

      您可以使用以下命令再次加载:

      read_back = loads(open('file_name.pon').read())
      print(read_back)
      

      给予:

      {'cats': {'sphinx': 3, 'british': 2}, 'dogs': {}}
      

      请注意loads() 确实评估字符串,它实际上使用 python 的内置解析器安全地解析它。

      PON 还允许您从具有注释条目的文件中加载 python 字典,并在保留 cmets 的同时转储它们。这就是它真正有用的地方。


      或者,如果您想要一些更易读的东西,例如 YAML 格式,您可以使用 ruamel.yaml 并执行以下操作:

      import ruamel.yaml
      ruamel.yaml.round_trip_dump(data, stream=open('file_name.yaml', 'wb'), indent=4) 
      

      这会给你一个文件file_name.yaml 的内容:

      cats:
          sphinx: 3
          british: 2
      dogs: {}
      

      它使用您似乎更喜欢的缩进(并且比@alberto 的版本更有效)

      【讨论】:

        猜你喜欢
        • 2013-10-12
        • 2017-07-14
        • 1970-01-01
        • 2014-11-04
        • 2012-06-18
        • 2013-08-06
        • 1970-01-01
        • 2016-03-29
        相关资源
        最近更新 更多