ruamel.yaml equivalent of sort_keys?

China☆狼群 提交于 2019-12-10 15:54:53

问题


I'm trying to dump a Python dict to a YAML file using ruamel.yaml. I'm familiar with the json module's interface, where pretty-printing a dict is as simple as

import json
with open('outfile.json', 'w') as f:
    json.dump(mydict, f, indent=4, sort_keys=True)

With ruamel.yaml, I've gotten as far as

import ruamel.yaml
with open('outfile.yaml', 'w') as f:
    ruamel.yaml.round_trip_dump(mydict, f, indent=2)

but it doesn't seem to support the sort_keys option. ruamel.yaml also doesn't seem to have any exhaustive docs, and searching Google for "ruamel.yaml sort" or "ruamel.yaml alphabetize" didn't turn up anything at the level of simplicity I'd expect.

Is there a one-or-two-liner for pretty-printing a YAML file with sorted keys?

(Note that I need the keys to be alphabetized down through the whole container, recursively; just alphabetizing the top level is not good enough.)


Notice that if I use round_trip_dump, the keys are not sorted; and if I use safe_dump, the output is not "YAML-style" (or more importantly "Kubernetes-style") YAML. I don't want [] or {} in my output.

$ pip freeze | grep yaml
ruamel.yaml==0.12.5

$ python
>>> import ruamel.yaml
>>> mydict = {'a':1, 'b':[2,3,4], 'c':{'a':1,'b':2}}
>>> print ruamel.yaml.round_trip_dump(mydict)  # right format, wrong sorting
a: 1
c:
  a: 1
  b: 2
b:
- 2
- 3
- 4

>>> print ruamel.yaml.safe_dump(mydict)  # wrong format, right sorting
a: 1
b: [2, 3, 4]
c: {a: 1, b: 2}

回答1:


This:

import sys
import ruamel.yaml

mydict = dict(a1=1, a2=2, a3=3, a11=11, a21=21)
ruamel.yaml.round_trip_dump(mydict, sys.stdout)

gives non-sorted output. On my system:

a11: 11
a2: 2
a21: 21
a3: 3
a1: 1

by adding:

my_sorted_dict = ruamel.yaml.comments.CommentedMap()
for k in sorted(mydict):
    my_sorted_dict[k] = mydict[k]
ruamel.yaml.round_trip_dump(my_sorted_dict, sys.stdout)

this will be sorted:

a1: 1
a11: 11
a2: 2
a21: 21
a3: 3

The commented map is the structure ruamel.yaml uses when doing a round-trip (load+dump) and round-tripping is designed to keep the keys in the order that they were before.

If you loaded mydict from a YAML file and only need to add a few keys, you can also walk over mydict's keys and insert (mydict.insert(pos, new_key, new_value)) the key value pairs.

Of course you can get the same output by doing a normal safe_dump() if you don't need any of the other special features:

ruamel.yaml.safe_dump(mydict, sys.stdout, allow_unicode=True, 
                      default_flow_style=False)


来源:https://stackoverflow.com/questions/40226610/ruamel-yaml-equivalent-of-sort-keys

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!