Can PyYAML dump dict items in non-alphabetical order?

后端 未结 10 775
一向
一向 2020-11-29 03:38

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\":         


        
10条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-29 04:38

    One-liner to rule them all:

    yaml.add_representer(dict, lambda self, data: yaml.representer.SafeRepresenter.represent_dict(self, data.items()))
    

    That's it. Finally. After all those years and hours, the mighty represent_dict has been defeated by giving it the dict.items() instead of just dict

    Here is how it works:

    This is the relevant PyYaml source code:

        if hasattr(mapping, 'items'):
            mapping = list(mapping.items())
            try:
                mapping = sorted(mapping)
            except TypeError:
                pass
        for item_key, item_value in mapping:
    

    To prevent the sorting we just need some Iterable[Pair] object that does not have .items().

    dict_items is a perfect candidate for this.

    Here is how to do this without affecting the global state of the yaml module:

    #Using a custom Dumper class to prevent changing the global state
    class CustomDumper(yaml.Dumper):
        #Super neat hack to preserve the mapping key order. See https://stackoverflow.com/a/52621703/1497385
        def represent_dict_preserve_order(self, data):
            return self.represent_dict(data.items())    
    
    CustomDumper.add_representer(dict, CustomDumper.represent_dict_preserve_order)
    
    return yaml.dump(component_dict, Dumper=CustomDumper)
    

提交回复
热议问题