用python从yaml读取并转储[bracket,list]

2024-10-01 00:36:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用以下代码读取列表并将其转储到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

如何获得与输入相同的输出?你知道吗


Tags: path代码yaml列表aswithloadopen
3条回答

如果您想先加载,然后转储(可能在修改一些值之后),PyYAML不是合适的工具,因为它会破坏语法表示中的许多内容。你知道吗

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

在PyYAML中,对输出的flow-vs-block样式几乎没有控制。您可以将所有块;节点集合作为流,
您可以使用default_flow_style参数safe_dump()来拥有所有流。你知道吗

最好使用ruamel.yaml(免责声明:我是该库的作者),因为它支持已有10年历史的yaml1.2标准(其中PyYAML只处理过时的yaml1.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)

默认情况下,任何新的列表(和dict)都将是块样式,如果要添加流样式列表,则可以使用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"])

正如前面提到的here,使用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()参数。你知道吗

By default, PyYAML chooses the style of a collection depending on whether it has nested collections. If a collection has nested collections, it will be assigned the block style. Otherwise it will have the flow style.

If you want collections to be always serialized in the block style, set the parameter default_flow_style of dump() to False.

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

相关问题 更多 >