Search code examples
pythonyamlpyyaml

How to start listing keys after a new line in a block


Using the built-in yaml package in Python is it possible to dump the items of a list starting in a new line after the list indicator dash?

Instead of this structure:

root:
  - name: a
    id: 0
  - name: b
    id: 1

I need the following structure:

root:
  -
    name: a
    id: 0
  -
    name: b
    id: 1

Solution

  • AFAIK PyYAML doesn't even support the first output that you indicate:

    import sys
    import yaml as pyyaml
    
    data = dict(root=[dict(name="a", id=0), dict(name="b", id=1)])
    pyyaml.safe_dump(data, sys.stdout, default_flow_style=False, indent=4)
    

    as this gives:

    root:
    -   id: 0
        name: a
    -   id: 1
        name: b
    

    As you can see the block sequence item indicator (-) is not offset within the indent of the sequence item, and to do that and/or to get the extra line newline, you would have to change theinternals of PyYAML's emitter.

    The other built-in YAML library, ruamel.yaml (disclaimer: I am the author of that package), can do exactly what you want:

    import sys
    import ruamel.yaml
    
    data = dict(root=[dict(name="a", id=0), dict(name="b", id=1)])
    
    yaml = ruamel.yaml.YAML()
    yaml.indent(sequence=4, offset=2)
    yaml.compact_seq_map = False
    
    yaml.dump(data, sys.stdout)
    

    which gives:

    root:
      -
        name: a
        id: 0
      -
        name: b
        id: 1
    

    BTW I would call neither PyYAML nor ruamel.yaml built-in, whatever you mean by that. Python has a standard library (as it comes with batteries included), which e.g. contains a JSON parser. But there is no YAML parser in the standard library.