繁体   English   中英

在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规范使用!!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到orderdict实现和vv的某些映射,就无法使用PyYAML解决该问题。

您需要为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的本质。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM