在 python 中对 YAML 块映射序列进行排序
sort a YAML block mapping sequence in python
我正在尝试按照我想要的方式对 YAML 块映射序列进行排序...我想要类似的东西
depth: !!opencv-matrix
rows: 480
cols: 640
dt: f
data: 'x'
但每次我倾倒时,它都会变成
cols: 640
data: 'x'
depth: !!opencv-matrix
dt: f
rows: 480
我在这里使用
检查了一种简单易行的方法
ordering = ['ymlFile','depth', 'rows', 'cols', 'dt', 'data']
ordered_set = [{'depth': '!!opencv-matrix'}, {'rows' : depthSizeImg[0]}, {'cols' : depthSizeImg[1]}, {'dt' : type(img_d[0][0])}, {'data': ymlList.tolist()}]]
f = open(out_d, 'a')
f.write('%YAML:1.0 \n')
f.write(yaml.dump(data, default_flow_style=None, allow_unicode=False, indent = 4))
f.close()
但它使 YAML 不是嵌套的。
%YAML:1.0
- {depth: '!!opencv-matrix'}
- {rows: 323}
- {cols: 110}
- {dt: !!python/name:numpy.float32 ''}
- {data: 'x'}
如何获得正确的输出?
在你的例子中
ordered_set = [{'depth': '!!opencv-matrix'}, {'rows' : depthSizeImg[0]}, {'cols' : depthSizeImg[1]}, {'dt' : type(img_d[0][0])}, {'data': ymlList.tolist()}]]
您正在转储一个字典列表,这就是您作为 YAML 输出获得的内容。调用列表 ordered_set
不会使其成为一个集合,并且在您的数据中包含 YAML 标签(那些 !!object_name
条目)也不会改变它们。
YAML specification 使用 !!omap
(示例 2.26),它将序列的有序结构与单键映射组合为元素:
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
如果您将其读入 PyYAML,您会得到:
{'depth': [('rows', 480), ('cols', 640), ('dt', 'f'), ('data', 'x')]}
这意味着您无法通过简单的关键字查找获得rows
的值。
如果将上面的内容转储到 YAML,你会变得更加丑陋:
depth:
- !!python/tuple [rows, 480]
- !!python/tuple [cols, 640]
- !!python/tuple [dt, f]
- !!python/tuple [data, x]
如果不定义从 !!omap
到 ordereddict 实现和 vv.
的一些映射,就无法使用 PyYAML 解决这个问题
您需要的是更智能的 "Dumper" YAML ¹:
import ruamel.yaml as yaml
yaml_str = """\
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
"""
data1 = yaml.load(yaml_str)
data1['depth']['data2'] = 'y'
print(yaml.dump(data1, Dumper=yaml.RoundTripDumper))
给出:
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
- data2: y
或者将其与智能加载程序(不会丢弃输入中存在的排序信息)结合使用,您可以省略 !!omap
:
import ruamel.yaml as yaml
yaml_str = """\
depth:
- rows: 480
- cols: 640 # my number of columns
- dt: f
- data: x
"""
data3 = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
print(yaml.dump(data3, Dumper=yaml.RoundTripDumper))
给出:
depth:
- rows: 480
- cols: 640 # my number of columns
- dt: f
- data: x
(包括保留的评论)。
¹ 这是使用 ruamel.yaml 完成的,我是作者。你应该可以
要在 PyYAML 中用 data1
做一些努力,如果没有 PyYAML 的主要增强,另一个例子就无法完成,这正是 ruamel.yaml 是什么。
我正在尝试按照我想要的方式对 YAML 块映射序列进行排序...我想要类似的东西
depth: !!opencv-matrix
rows: 480
cols: 640
dt: f
data: 'x'
但每次我倾倒时,它都会变成
cols: 640
data: 'x'
depth: !!opencv-matrix
dt: f
rows: 480
我在这里使用
检查了一种简单易行的方法ordering = ['ymlFile','depth', 'rows', 'cols', 'dt', 'data']
ordered_set = [{'depth': '!!opencv-matrix'}, {'rows' : depthSizeImg[0]}, {'cols' : depthSizeImg[1]}, {'dt' : type(img_d[0][0])}, {'data': ymlList.tolist()}]]
f = open(out_d, 'a')
f.write('%YAML:1.0 \n')
f.write(yaml.dump(data, default_flow_style=None, allow_unicode=False, indent = 4))
f.close()
但它使 YAML 不是嵌套的。
%YAML:1.0
- {depth: '!!opencv-matrix'}
- {rows: 323}
- {cols: 110}
- {dt: !!python/name:numpy.float32 ''}
- {data: 'x'}
如何获得正确的输出?
在你的例子中
ordered_set = [{'depth': '!!opencv-matrix'}, {'rows' : depthSizeImg[0]}, {'cols' : depthSizeImg[1]}, {'dt' : type(img_d[0][0])}, {'data': ymlList.tolist()}]]
您正在转储一个字典列表,这就是您作为 YAML 输出获得的内容。调用列表 ordered_set
不会使其成为一个集合,并且在您的数据中包含 YAML 标签(那些 !!object_name
条目)也不会改变它们。
YAML specification 使用 !!omap
(示例 2.26),它将序列的有序结构与单键映射组合为元素:
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
如果您将其读入 PyYAML,您会得到:
{'depth': [('rows', 480), ('cols', 640), ('dt', 'f'), ('data', 'x')]}
这意味着您无法通过简单的关键字查找获得rows
的值。
如果将上面的内容转储到 YAML,你会变得更加丑陋:
depth:
- !!python/tuple [rows, 480]
- !!python/tuple [cols, 640]
- !!python/tuple [dt, f]
- !!python/tuple [data, x]
如果不定义从 !!omap
到 ordereddict 实现和 vv.
您需要的是更智能的 "Dumper" YAML ¹:
import ruamel.yaml as yaml
yaml_str = """\
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
"""
data1 = yaml.load(yaml_str)
data1['depth']['data2'] = 'y'
print(yaml.dump(data1, Dumper=yaml.RoundTripDumper))
给出:
depth: !!omap
- rows: 480
- cols: 640
- dt: f
- data: x
- data2: y
或者将其与智能加载程序(不会丢弃输入中存在的排序信息)结合使用,您可以省略 !!omap
:
import ruamel.yaml as yaml
yaml_str = """\
depth:
- rows: 480
- cols: 640 # my number of columns
- dt: f
- data: x
"""
data3 = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
print(yaml.dump(data3, Dumper=yaml.RoundTripDumper))
给出:
depth:
- rows: 480
- cols: 640 # my number of columns
- dt: f
- data: x
(包括保留的评论)。
¹ 这是使用 ruamel.yaml 完成的,我是作者。你应该可以
要在 PyYAML 中用 data1
做一些努力,如果没有 PyYAML 的主要增强,另一个例子就无法完成,这正是 ruamel.yaml 是什么。