I am using Python 3.8.10
and ruamel 0.17.31
. I have this python dict
d = {'a': {'b': {'c': {'x': 1, 'y': 1}, 'd': [1, 2, 3], 'e': {'f': 1, 'g': 1} }}}
Using ruamel.yaml
, I want it to be printed like:
a:
b:
c:
x: 1
y: 1
d: [1, 2, 3]
e:
f: 1
g: 1
I think I am mixing the flow and block styles. By using the default_flow_style
I can either of the one output
a:
b:
c:
x: 1
y: 1
d:
- 1
- 2
- 3
e:
f: 1
g: 1
or
a:
b:
c: {x: 1, y: 1}
d: [1, 2, 3]
e: {f: 1, g: 1}
Do I need to write a custom representer?
You could write a custom representer that only emits sequences using flow-style when that sequence doesn't contain any collections itself (i.e. only contains scalars). That is non-trivial, and probably also not necessary.
As indicated in other answers, even if you don't know what to do, it is good to
check if ruamel.yaml
can round-trip what you want to get:
import sys
import ruamel.yaml
yaml_str = """\
a:
b:
c:
x: 1
y: 1
d: [1, 2, 3]
e:
f: 1
g: 1
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
which gives:
a:
b:
c:
x: 1
y: 1
d: [1, 2, 3]
e:
f: 1
g: 1
So it can round-trip what you want, After which you can inspect how your special item is constructed during loading:
flow_list = data['a']['b']['d']
print(type(flow_list), flow_list)
which then gives:
<class 'ruamel.yaml.comments.CommentedSeq'> [1, 2, 3]
So you need to construct a CommentedSeq
and searching for that and ruamel.yaml and flow-style
on StackOverflow should get you a limited list of answers (e.g.
this one )
To give a complete example to construct something from scratch and dump it:
import sys
import ruamel.yaml
def FSlist(l): # convert list into flow-style (default is block style)
from ruamel.yaml.comments import CommentedSeq
cs = CommentedSeq(l)
cs.fa.set_flow_style()
return cs
yaml = ruamel.yaml.YAML()
data = dict(a=dict(b=dict(c=dict(x=1, y=1), d=FSlist([1, 2, 3]), e=dict(f=1, g=1))))
yaml.dump(data, sys.stdout)
resulting in something close to what you wanted:
a:
b:
c:
x: 1
y: 1
d: [1, 2, 3]
e:
f: 1
g: 1