my question is very simple. I have a OrderredDict object with customized order, I want to convert it to yaml format. But it seems yaml.dump couldn't take Orderredict as an Input. Anyone know how to do it?
Asked
Active
Viewed 8,012 times
11
-
it seems that it considers it like a mere `dict`, you're right. – Jean-François Fabre Feb 28 '17 at 20:26
-
You have to customize it. See here, http://stackoverflow.com/questions/5121931/in-python-how-can-you-load-yaml-mappings-as-ordereddicts – juanpa.arrivillaga Feb 28 '17 at 20:35
-
@juanpa.arrivillaga any reason why not flagging as duplicate? Looks like a pretty good candidate to me. Me I've got my finger on the trigger. – Jean-François Fabre Feb 28 '17 at 20:37
-
go ahead. I was looking for a blog-post that implemented *exactly* what the OP wants, but can't find it. I've needed to do this before. – juanpa.arrivillaga Feb 28 '17 at 20:38
-
@Jean-FrançoisFabre This refers to output. The "supposed" duplicate only solves the input aspect of the problem. – Yonatan Simson May 19 '17 at 04:05
-
1@YonatanSimson okay, reopening. – Jean-François Fabre May 19 '17 at 08:20
-
1If those solutions fail, you could convert the `OrderedDict` to a `list` of `tuple`s and export that – Maarten Fabré May 19 '17 at 10:03
3 Answers
12
It looks like you want this solution, which adds a "representer" to YAML.
Assuming you have an object my_object
that consists of nested lists, dicts, and/or OrderedDicts ... you can dump this to YAML if you add these lines:
yaml.add_representer(OrderedDict, lambda dumper, data: dumper.represent_mapping('tag:yaml.org,2002:map', data.items()))
output = yaml.dump(my_object)
I also find it necessary to convert my tuples to lists:
yaml.add_representer(tuple, lambda dumper, data: dumper.represent_sequence('tag:yaml.org,2002:seq', data))

Ethan T
- 1,390
- 12
- 28
2
This works only for dictionary, not OrderedDict, but you may be able to convert it without losing the order.
If you are using PyYaml 5.1 or later, you can dump a dictionary in its current order by simply using
yaml.dump(data, default_flow_style=False, sort_keys=False)

Phil B
- 5,589
- 7
- 42
- 58
1
Maybe this is what you need?
import yaml
from collections import OrderedDict
def dump_ordered_yaml(ordered_data, output_filename, Dumper=yaml.Dumper):
class OrderedDumper(Dumper):
pass
class UnsortableList(list):
def sort(self, *args, **kwargs):
pass
class UnsortableOrderedDict(OrderedDict):
def items(self, *args, **kwargs):
return UnsortableList(OrderedDict.items(self, *args, **kwargs))
OrderedDumper.add_representer(UnsortableOrderedDict, yaml.representer.SafeRepresenter.represent_dict)
with open(output_filename, "w") as f:
yaml.dump(ordered_data, f, Dumper=OrderedDumper)
Usage:
a = OrderedDict([('x', 11), ('y', 22)])
dump_ordered_yaml(a, "/tmp/ordered.yaml")
Result from terminal:
cat /tmp/ordered.yaml
!!python/object/apply:collections.OrderedDict
- - [x, 11]
- [y, 22]

Yonatan Simson
- 2,395
- 1
- 24
- 35