I am using ruamel.yaml to create a YAML file from a Python dictionary. 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:
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). 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 (e.g string), I get it from a csv-sheet.
UPDATE, here is a code example of what I've been trying:
A CSV-line looks like this:
"","",Parameter 1,Dropdown,kg,"","","A,B,C,1,2,3"
and in the conversion.py something like:
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'
)
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.
Then to fine-control a single list flow style you need to add that list as a
CommentedSeq
and call the set_flow_style()
method on its fa
attribute:
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 using a "normal" list. But that will affect all other "leaf-node" lists and dicts as well.