Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruamel yaml formatting of dumped nested lists

I would like to dump a dictionary with components that are nested lists, where each row of the list is on its own line. I also want to maintain dictionary order.

Here's a MWE:

import sys

from ruamel import yaml
from ruamel.yaml import YAML

d = {'b':1,
     'a':[[1, 2],[3, 4]]}

# desired output:
# b: 1
# a:
# - [1, 2]
# - [3, 4]

print()
yaml.dump(d, sys.stdout)
print('\n')
YAML().dump(d, sys.stdout)

And here's what I actually get:

a:
- [1, 2]
- [3, 4]
b: 1


b: 1
a:
- - 1
  - 2
- - 3
  - 4

The first method has the nested-list formatting I want, but loses dictionary order. (Not a surprise since I'm not using a round-trip dumper) The second method manages to maintain order, but loses my desired nested list formatting. Any time I use a round-trip dumper, I've lost the nice nested list formatting.

Any tips here?

like image 957
jrinker Avatar asked Sep 11 '25 11:09

jrinker


1 Answers

That your dictionary has the order you want is either luck, or because you are using Python 3.6. In older versions of Python (i.e < 3.6) this order is not guaranteed.

If you are only targeting 3.6 and have ruamel.yaml>=0.15.32 you can do:

import sys

from ruamel import yaml
from ruamel.yaml import YAML


d = {'b':1,
     'a':[[1, 2],[3, 4]]}

y = YAML()
y.default_flow_style = None
y.dump(d, sys.stdout)

if you have an older version and Python 3.6:

import sys

from ruamel import yaml
from ruamel.yaml import YAML

y = YAML()

d = {'b':1,
     'a':[y.seq([1, 2]),y.seq([3, 4])]}


for seq in d['a']:
    seq.fa.set_flow_style()
y.dump(d, sys.stdout)

to get:

b: 1
a:
- [1, 2]
- [3, 4]

to get the order you want in older versions of Python consistently you should do:

d = y.map()
d['b'] = 1
d['a'] = y.seq([1, 2]),y.seq([3, 4])

and with ruamel.yaml>=0.15.32 you can leave out the call to y.seq().

like image 62
Anthon Avatar answered Sep 13 '25 00:09

Anthon