使用 python 从 yaml 读取和转储 [括号,列表]



我正在尝试使用以下代码读取列表并将其转储到 yaml

with open(system_bsc_path) as f:
system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
yaml.safe_dump(system_bsc_dict, f)

输入列表,如文件中所示:

chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
[[16, 17, 18, 19, 20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
[[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]

被正确地读入 Python


转储的输出:

chs_per_cath:
- - - 10
- 11
- 12
- 13
- - 13000
- 13100
- 13200
- 13300
- - - 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- - 13400
- 13500
- 13600
- 13700
- 13800
- 13900
- 14000
- 14100
- 14200
- 14300
- - - 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- - 13400
- 13500
- 13600
- 13700
- 13800
- 13900
- 14000
- 14100
- 14200
- 14300

如何获得与输入相同的输出?

如果你想加载,然后转储(也许在修改了一些值之后),PyYAML不是正确的工具,因为它会在语法表示中破坏很多东西。

正如您注意到的那样,它将删除流样式,但也会删除注释、锚点/别名、特定的整数格式(八进制、十六进制、二进制)等。

在PyYAML 中,对输出的流与块样式几乎没有控制。你可以有全块;节点集合作为流,
并且可以拥有全流,使用default_flow_style参数来safe_dump()

你最好使用ruamel.yaml(免责声明:我是该库的作者),因为它支持现在已有 10 年历史的 YAML 1.2 标准(其中 PyYAML 只处理过时的 YAML 1.1),并且会让你输出更接近,并且通常与您的 YAML 输入相同。

from ruamel.yaml import YAML
yaml = YAML()
with open(system_bsc_path) as f:
system_bsc_dict = yaml.load(f)
with open(system_bsc_path, "w") as f:
yaml.dump(system_bsc_dict, f)

如果你是 Python 3,你可以使用:

from pathlib import Path
yaml_file = Path(system_bsc_path)
system_bsc_dict = yaml.load(yaml_file)
yaml.dump(system_bsc_dict, yaml_file)

默认情况下,任何列表(和字典)都将是块样式,如果要添加流样式列表,则可以使用yaml.default_flow_style = True来设置所有这些列表,或者通过在特殊内部表示上设置流属性(.fa)来使用精细控制:

def FSlist(l):  # concert list into flow-style (default is block style)
from ruamel.yaml.comments import CommentedSeq
cs = CommentedSeq(l)
cs.fa.set_flow_style()
return cs
system_bsc_dict['existing_field'] = FSlist(["Boston Maestro 4000"])

正如这里提到的,使用default_flow_style应该可以解决问题。

但似乎您实际上需要将其设置为True.

>>> d = {'chs_per_cath': [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]],
[[16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
[13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]],
[[32, 33, 34, 35, 36, 37, 38, 39, 40, 41],
[13400, 13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}
>>> print(yaml.dump(d, default_flow_style=True))
{chs_per_cath: [[[10, 11, 12, 13], [13000, 13100, 13200, 13300]], [[16, 17, 18, 19,
20, 21, 22, 23, 24, 25], [13400, 13500, 13600, 13700, 13800, 13900, 14000,
14100, 14200, 14300]], [[32, 33, 34, 35, 36, 37, 38, 39, 40, 41], [13400,
13500, 13600, 13700, 13800, 13900, 14000, 14100, 14200, 14300]]]}

请看一下default_flow_styleyaml.dump()的论据。

默认情况下,PyYAML 根据以下条件选择集合的样式 它是否具有嵌套集合。如果集合已嵌套 集合,它将被分配块样式。否则会 有流动风格。

如果希望集合始终以块样式序列化, 将 dump() 的参数 default_flow_style 设置为 False。

https://pyyaml.org/wiki/PyYAMLDocumentation#DumpingYAML

最新更新