简体   繁体   English

将 Python 中的列表显示为块样式 yaml 文件 (ruamel.yaml) 中的流样式

[英]Display a list from Python as flow style inside a block style yaml file (ruamel.yaml)

I am using ruamel.yaml to create a YAML file from a Python dictionary.我正在使用 ruamel.yaml 从 Python 字典创建 YAML 文件。 Within the dictionary, there's a list as the value for the 'type' key.在字典中,有一个列表作为“类型”键的值。 I've been looking all day now for examples to solve my problem, but can't find anything in the docs.我整天都在寻找解决问题的示例,但在文档中找不到任何内容。

I've been trying to get a YAML file output like this:我一直在尝试像这样获取 YAML 文件 output :

 some_key:
  - id: 1059
    parameter: Paramter1
    unit: kg
    type: [A, B, C, 1, 2, 3]

That means the list after type is a flow-style element within the block style, which is the actual reason I switched to ruamel.yaml , because I read that it might be possible as opposed to PyYAML ( Mixing block and flow formatting in YAML with Python ).这意味着类型后的列表是块样式中的流样式元素,这就是我切换到ruamel.yaml的实际原因,因为我读到它可能与 PyYAML 不同( 在 YAML 中混合块和流格式与Python )。 But in there I couldn't find what I am trying to do.但在那里我找不到我想要做的事情。

What I (unsurprisingly) get when I call当我打电话时,我(不出所料)得到什么

yaml.dump() 

on the dictionary is字典上是

some_key:
  - id: 1059
    parameter: Paramter1
    unit: kg
    type:
          - A 
          - B
          - C
          - '1'
          - '2'
          - '3'

Does anyone have a clue how this is solvable?有谁知道这是如何解决的? A useful information might or might not be, that the list concerned could also be converted to different formats (eg string), I get it from a csv-sheet.一个有用的信息可能是也可能不是,相关列表也可以转换为不同的格式(例如字符串),我从 csv 表中得到它。

UPDATE, here is a code example of what I've been trying:更新,这是我一直在尝试的代码示例:

A CSV-line looks like this: CSV 行如下所示:

"","",Parameter 1,Dropdown,kg,"","","A,B,C,1,2,3"

and in the conversion.py something like:在conversion.py中类似:

with open(csv_filename, "r") as file:
reader = csv.reader(file)
data = {"some_key": []}
for position, line in enumerate(reader):
        if line[3] == "Dropdown":
            select_options = []
            for item in line[7].split(","):
                select_options.append(item)
            select_options = [x.strip(" ") for x in select_options]
            type = f"{select_options}"
        dict = {
            "id": "tbd",
            "parameter": line[2].strip(" "),
            "unit": line[4].strip(" "),
            "type": type,
        }
        data["some_key"].append(dict)
doc = yaml.dump(data, file)

First of all you need to define numbers as numbers, and not as strings, to get the output of those non-quoted ( 3 instead of '3' )首先,您需要将数字定义为数字,而不是字符串,以获取未引用的 output ( 3而不是'3'

Second you need to call yaml.indent() as the sequence indent of 3 positions with an offset for the sequence delimiter of 1, is non-standard.其次,您需要调用yaml.indent()因为序列定界符的偏移量为 1 的 3 个位置的序列缩进是非标准的。

Then to fine control a single list flow style you need to add that list as a CommentedSeq and call the set_flow_style() methode on its fa attribute:然后要精细控制单个列表流样式,您需要将该列表添加为CommentedSeq并在其fa属性上调用set_flow_style()方法:

import sys
import ruamel.yaml

def seq(*l):
    s = ruamel.yaml.comments.CommentedSeq(l)
    s.fa.set_flow_style()
    return s

data = dict(some_key=[{'id': 1059,
                       'parameter': 'Paramter1',
                       'unit': 'kg',
                       'type': seq('A', 'B', 'C', 1, 2 ,3)}])


yaml = ruamel.yaml.YAML()
yaml.indent(mapping=2, sequence=3, offset=1)
yaml.dump(data, sys.stdout)

which gives:这使:

some_key:
 - id: 1059
   parameter: Paramter1
   unit: kg
   type: [A, B, C, 1, 2, 3]

In your example, you could have set yaml.default_flow_style = None before dumping and use a "normal" list.在您的示例中,您可以在转储之前设置yaml.default_flow_style = None并使用“正常”列表。 But that will affected all other "leaf-node" lists and dicts as well.但这也会影响所有其他“叶节点”列表和字典。

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

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