Reputation: 14705
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
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
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