yabchexu
yabchexu

Reputation: 593

How to use OrderedDict as an input in yaml.dump or yaml.safe_dump?

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?

Upvotes: 15

Views: 11170

Answers (3)

Phil B
Phil B

Reputation: 6037

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)

Upvotes: 4

Ethan T
Ethan T

Reputation: 1490

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))

Upvotes: 18

Yonatan Simson
Yonatan Simson

Reputation: 2575

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]

Upvotes: 1

Related Questions