I'm using yaml.dump
to output a dict. It prints out each item in alphabetical order based on the key.
>>> d = {"z":0,"y":0,"x":0}
>>> yaml.dump( d, default_flow_style=False )
'x: 0\ny: 0\nz: 0\n'
Is there a way to control the order of the key/value pairs?
In my particular use case, printing in reverse would (coincidentally) be good enough. For completeness though, I'm looking for an answer that shows how to control the order more precisely.
I've looked at using collections.OrderedDict
but PyYAML doesn't (seem to) support it. I've also looked at subclassing yaml.Dumper
, but I haven't been able to figure out if it has the ability to change item order.
I was also looking for an answer to the question "how to dump mappings with the order preserved?" I couldn't follow the solution given above as i am new to pyyaml and python. After spending some time on the pyyaml documentation and other forums i found this.
You can use the tag
!!omap
to dump the mappings by preserving the order. If you want to play with the order i think you have to go for keys:values
The links below can help for better understanding.
https://bitbucket.org/xi/pyyaml/issue/13/loading-and-then-dumping-an-omap-is-broken
http://yaml.org/type/omap.html
This is really just an addendum to @Blender's answer. If you look in the
PyYAML
source, at therepresenter.py
module, You find this method:If you simply remove the
mapping.sort()
line, then it maintains the order of items in theOrderedDict
.Another solution is given in this post. It's similar to @Blender's, but works for
safe_dump
. The common element is the converting of the dict to a list of tuples, so theif hasattr(mapping, 'items')
check evaluates to false.Update:
I just noticed that The Fedora Project's EPEL repo has a package called
python2-yamlordereddictloader
, and there's one for Python 3 as well. The upstream project for that package is likely cross-platform.Building on @orodbhen's answer:
Just replace the built-in function sorted by a lambda identity function while you use yaml.dump.
There are two things you need to do to get this as you want:
dict
, because it doesn't keep the items orderedoutput:
¹ This was done using ruamel.yaml a YAML 1.2 parser, of which I am the author.
There's probably a better workaround, but I couldn't find anything in the documentation or the source.
Python 2 (see comments)
I subclassed
OrderedDict
and made it return a list of unsortable items:And it seems to work:
Python 3 or 2 (see comments)
You can also write a custom representer, but I don't know if you'll run into problems later on, as I stripped out some style checking code from it:
But with that, you can use the native
OrderedDict
class.For Python 3.7+, dicts preserve insertion order. It's best to use a library which respects that, such as oyaml: