在保留顺序的同时将字典转储到YAML文件

Ben*_*Ben 8 dictionary yaml python-3.x

我一直在尝试将字典转储到YAML文件中.问题是导入YAML文件的程序需要按特定顺序的关键字.此订单不是按字母顺序排列的.

import yaml
import os 

baseFile = 'myfile.dat'
lyml = [{'BaseFile': baseFile}]
lyml.append({'Environment':{'WaterDepth':0.,'WaveDirection':0.,'WaveGamma':0.,'WaveAlpha':0.}})

CaseName = 'OrderedDict.yml'
CaseDir = r'C:\Users\BTO\Documents\Projects\Mooring code testen'
CaseFile = os.path.join(CaseDir, CaseName)
with open(CaseFile, 'w') as f:
    yaml.dump(lyml, f, default_flow_style=False)
Run Code Online (Sandbox Code Playgroud)

这会生成一个*.yml文件,其格式如下:

- BaseFile: myfile.dat
- Environment:
    WaterDepth: 0.0
    WaveAlpha: 0.0
    WaveDirection: 0.0
    WaveGamma: 0.0
Run Code Online (Sandbox Code Playgroud)

但我想要的是订单保留:

- BaseFile: myfile.dat
- Environment:
    WaterDepth: 0.0
    WaveDirection: 0.0
    WaveGamma: 0.0
    WaveAlpha: 0.0
Run Code Online (Sandbox Code Playgroud)

这可能吗?

小智 35

3 年后 - yaml.dump 有一个 sort_keys kwarg,默认设置为 True。将其设置为 False 以不重新排序:

with open(CaseFile, 'w') as f:
    yaml.dump(lyml, f, default_flow_style=False, sort_keys=False)
Run Code Online (Sandbox Code Playgroud)

  • `TypeError: dump_all() 得到了意外的关键字参数 'sort_keys'` (2认同)

bal*_*lki 29

使用OrderedDict而不是dict.在开始时运行以下设置代码.现在yaml.dump,应该保留订单.更多细节在这里这里

def setup_yaml():
  """ https://stackoverflow.com/a/8661021 """
  represent_dict_order = lambda self, data:  self.represent_mapping('tag:yaml.org,2002:map', data.items())
  yaml.add_representer(OrderedDict, represent_dict_order)    
setup_yaml()
Run Code Online (Sandbox Code Playgroud)

示例:https://pastebin.com/raw.php?i = NpcT6Yc4


Aki*_*kif 5

PyYAML支持representer将类实例序列化为YAML节点。

yaml.YAMLObject使用元类魔术来注册一个构造函数和一个表示程序,该构造函数将YAML节点转换为类实例,并将表示形式的类实例序列化为YAML节点。

在代码上方添加以下行:

def represent_dictionary_order(self, dict_data):
    return self.represent_mapping('tag:yaml.org,2002:map', dict_data.items())

def setup_yaml():
    yaml.add_representer(OrderedDict, represent_dictionary_order)

setup_yaml()
Run Code Online (Sandbox Code Playgroud)

然后,您可以OrderedDict用来保留订单yaml.dump()

import yaml
from collections import OrderedDict

def represent_dictionary_order(self, dict_data):
    return self.represent_mapping('tag:yaml.org,2002:map', dict_data.items())

def setup_yaml():
    yaml.add_representer(OrderedDict, represent_dictionary_order)

setup_yaml()    

dic = OrderedDict()

dic['a'] = 1
dic['b'] = 2
dic['c'] = 3

print(yaml.dump(dic))
# {a: 1, b: 2, c: 3}
Run Code Online (Sandbox Code Playgroud)