Sundar R
Sundar R

Reputation: 14705

Numbered list as YAML array

Instead of

key:
    - thisvalue
    - thatvalue
    - anothervalue

I would like to have

key:
    1. thisvalue
    2. thatvalue
    3. anothervalue

purely for human readability, with the same interpretation of {key: [thisvalue, thatvalue, anothervalue]}.

This doesn't seem to be part of the basic YAML syntax, but is there a way to achieve this - perhaps using some of the advanced arcanery that's possible in YAML?

(I realize that this can be approximated by writing the list as:

key:
    - 1. thisvalue
    - 2. thatvalue
    - 3. anothervalue

but this is an ugly hack and I'd prefer a solution where the numbers had semantic purpose, rather than being just part of the value's text, that also requires being parsed and removed.)

Upvotes: 6

Views: 10962

Answers (2)

Anthon
Anthon

Reputation: 76682

When using Python, in order to be able to preserve the key order in YAML mappings (and comments, anchor names etc), the mappings are read into special ordereddict derivatives if you use ruamel.yaml (diclaimer: I am the author) and the RoundTripLoader.

Those function as dicts transparently, but with that, and using the syntax proposed by rbaleksandar in her/his answer, you can just do:

import ruamel.yaml as yaml

yaml_str = """\
key:
    1: thisvalue
    2: thatvalue
    3: anothervalue
    4: abc
    5: def
    6: ghi
"""

data = yaml.load(yaml_str, Loader=yaml.RoundTripLoader)
y = data['key']
print y.keys()[2:5]
print y.values()[2:5]
print y.items()[2:5]

to get:

[3, 4, 5]
['anothervalue', 'abc', 'def']
[(3, 'anothervalue'), (4, 'abc'), (5, 'def')]

without any special effort after loading the data.

The YAML specs state that the key ordering is not guaranteed, but in the YAML file they are of course ordered. If the parser doesn't throw this information awasy, things are much more useful e.g. for comparison between revisions of a file.

Upvotes: 2

rbaleksandar
rbaleksandar

Reputation: 9701

There is no way to do that in YAML. You can however use a normal nesting of elements and then during parsing generate an array/list/dictionary based on those:

my_numbered_pseudo_list:
  1: a
  2: b
  3: c
  ...
  n: x

When you load the example from above you will get the dictionary with key "my_numbered_pseudo_list" and its value as a dictionary containing all nested pairs {"1" : "a", "2" : "b", ..., "n" : "x"}. Here is an example how it will look like:

import yaml

doc = '''
list:
  1: a
  2: b
  3: c
  4: d
'''

y = yaml.load(doc);
list = []

for i in y['list']:
    list.append(y['list'].get(i))

print list

This will give you

['a', 'b', 'c', 'd']

If you want to make sure that the order is actually kept in the YAML file you have to do some sorting in order to get an ordered final list where the order described in the YAML file is kept.

I have also seen people use ordered hash calls on the resulting dictionary (here: "list") (such as in Ruby which I am not familiar with) so you might want to dig a little bit more.

IMPORTANT!

Read here and here. In short to make sure you get a really ordered list from your YAML you have to sort the dictionary you have as a pseudo-list by key and then extract the values and append those to your final list.

Upvotes: 5

Related Questions