在python中排序一个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规范使用!!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就无法解决这个问题。

您需要的是为您的YAML提供一个更智能的"dump"¹:

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完成的。我是它的作者。你应该能够为了在PyYAML中完成data1的示例,如果没有PyYAML的主要增强,则无法完成其他示例,这正是我所做的。yaml。

最新更新