javanix
javanix

Reputation: 1330

Prettily dump 2D array to YAML in Python

Suppose I have a 2D array defined like so:

import sys

from ruamel.yaml import YAML

yaml = YAML()
yaml.version = (1,2)

def main():
    data = {
        "foo": [
            [1,2,3],
            [4,5,6]
        ]
    }
    yaml.dump(data, sys.stdout)

if __name__ == '__main__':
    main()

I would like to output a "readable", valid YAML file with each "row" on a separate line:

"foo":
- [1,2,3]
- [4,5,6]

or even

"foo": [
  [1,2,3],
  [4,5,5]
]

I've looked into ruamel.yaml but the default behavior is each column on a separate line which, while valid, is not easily readable:

%YAML 1.2
---
foo:
- - 1
  - 2
  - 3
- - 4
  - 5
  - 6

Upvotes: 3

Views: 6396

Answers (1)

Anthon
Anthon

Reputation: 76742

When you set the attribute .default_flow_style to None (instead of the default value False), your leaf-nodes will be represented in flow style:

import sys
import ruamel.yaml


yaml = ruamel.yaml.YAML()
yaml.version = (1,2)
yaml.default_flow_style = None

def main():
    data = {
        "foo": [
            [1,2,3],
            [4,5,6]
        ]
    }
    yaml.dump(data, sys.stdout)

if __name__ == '__main__':
    main()

which gives:

%YAML 1.2
---
foo:
- [1, 2, 3]
- [4, 5, 6]

But the above works for the whole file.

If you want an individual lists to be represented as flow-style sequences in YAML, you should make them of the type CommentedSeq and then you can set the attribute per object. That is also the way ruamel.yaml "knows" how to preserve the style of a sequence when round-tripping:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()
yaml.version = (1,2)

a = ruamel.yaml.comments.CommentedSeq([1,2,3])
a.fa.set_flow_style()


def main():
    data = {
        "foo": [
        a,
            [4,5,6]
        ]
    }
    yaml.dump(data, sys.stdout)

if __name__ == '__main__':
    main()

giving:

%YAML 1.2
---
foo:
- [1, 2, 3]
- - 4
  - 5
  - 6

Upvotes: 5

Related Questions