我试图使用ruamel.yaml将Python转储到YAML文件中。我很熟悉json模块的接口,其中漂亮的打印一条数据集非常简单
import json
with open('outfile.json', 'w') as f:
json.dump(mydict, f, indent=4, sort_keys=True)对于ruamel.yaml,我已经做到了
import ruamel.yaml
with open('outfile.yaml', 'w') as f:
ruamel.yaml.round_trip_dump(mydict, f, indent=2)但它似乎不支持sort_keys选项。ruamel.yaml也是似乎没有任何详尽的文档,在谷歌上搜索"ruamel.yaml排序“或"ruamel.yaml字母化”,并没有在我期望的简单程度上找到任何东西。
是否有一条或两条线用来打印带有排序密钥的YAML文件?
(请注意,我需要在整个容器中递归地按字母顺序排列键;仅仅按字母顺序排列顶层是不够的。)
注意,如果我使用round_trip_dump,键就没有排序;如果我使用safe_dump,输出就不是“YAML样式”(或者更重要的是“Kubernetes-样式”)。我不希望[]或{}在我的输出中。
$ 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}发布于 2016-10-24 21:05:12
您需要一些处理映射/dicts、序列/列表的递归函数:
import sys
import ruamel.yaml
CM = ruamel.yaml.comments.CommentedMap
yaml = ruamel.yaml.YAML()
data = dict(a=1, c=dict(b=2, a=1), b=[2, dict(e=6, d=5), 4])
yaml.dump(data, sys.stdout)
def rec_sort(d):
try:
if isinstance(d, CM):
return d.sort()
except AttributeError:
pass
if isinstance(d, dict):
# could use dict in newer python versions
res = ruamel.yaml.CommentedMap()
for k in sorted(d.keys()):
res[k] = rec_sort(d[k])
return res
if isinstance(d, list):
for idx, elem in enumerate(d):
d[idx] = rec_sort(elem)
return d
print('---')
yaml.dump(rec_sort(data), sys.stdout)这意味着:
a: 1
c:
b: 2
a: 1
b:
- 2
- e: 6
d: 5
- 4
---
a: 1
b:
- 2
- d: 5
e: 6
- 4
c:
a: 1
b: 2注释映射是ruamel.yaml在执行往返(load+dump)时使用的结构,而往返是为了保持键在加载期间的顺序。
当您从注释的YAML文件加载data时,上面的注释应该能合理地保留对映射/序列的注释。
发布于 2020-10-14 18:55:04
在sort()中有一个无文档的ruamel.yaml,它将处理这个问题的一个变体:
import sys
import ruamel.yaml
yaml = ruamel.yaml.YAML()
test = """- name: a11
value: 11
- name: a2
value: 2
- name: a21
value: 21
- name: a3
value: 3
- name: a1
value: 1"""
test_yml = yaml.load(test)
yaml.dump(test_yml, sys.stdout)未排序输出
- name: a11
value: 11
- name: a2
value: 2
- name: a21
value: 21
- name: a3
value: 3
- name: a1
value: 1按名称排序
test_yml.sort(lambda x: x['name'])
yaml.dump(test_yml, sys.stdout)排序输出
- name: a1
value: 1
- name: a11
value: 11
- name: a2
value: 2
- name: a21
value: 21
- name: a3
value: 3发布于 2021-10-04 09:33:38
正如@Anthon示例中指出的那样,如果您使用的是Python3.7或更高版本(并且不需要支持更低的版本),您只需要:
import sys
from ruamel.yaml import YAML
yaml = YAML()
data = dict(a=1, c=dict(b=2, a=1), b=[2, dict(e=6, d=5), 4])
def rec_sort(d):
if isinstance(d, dict):
res = dict()
for k in sorted(d.keys()):
res[k] = rec_sort(d[k])
return res
if isinstance(d, list):
for idx, elem in enumerate(d):
d[idx] = rec_sort(elem)
return d
yaml.dump(rec_sort(data), sys.stdout)因为dict是从那个版本开始订购的。
https://stackoverflow.com/questions/40226610
复制相似问题