You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ruamel.yaml中CommentedMap元素排序及通用排序方案实现问题

YAML文件加载后通用排序导出实现方案

需求说明

需要实现加载YAML文件后按指定规则排序再导出的功能,原有仅能针对devices数组的hostName字段排序的逻辑需要改造为通用能力。

原有示例YAML内容

devices:
#list of devices    #list of devices
  - hostName: testhb200
    hostNetwork: 192.178.101.0
    hostMask: 255.255.255.255
  - hostName: testha100
    hostNetwork: 192.178.225.12
    hostMask: 255.255.255.252
    hostGateway: 192.178.225.13
    hostIp: 192.168.225.14
    vendor: vendor
    model: qfx5200-

原有YAML工具类实现

# YAML settings
class YamlUtil:
    logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))

    # YAML settings
    _yaml = YAML(typ="rt")
    _yaml.default_flow_style = False
    _yaml.explicit_start = False
    _yaml.preserve_quotes = True
    _yaml.indent(mapping=2, sequence=4, offset=2)
    _yaml.Representer.add_representer(OrderedDict,
                                      _yaml.Representer.represent_dict)

    def __init__(self, yaml: YAML = _yaml):
        # Override default class yaml settings
        self.yaml = yaml

    def load_file(self, file):
        with open(file, "r") as f:
            return self.yaml.load(f)

    def dump_file(self, data, file):
        with open(file, "w") as f:
            self.yaml.dump(data, f)

原有固定排序逻辑

yml = YamlUtil().load_file(args.input)
yml['devices'].sort(lambda x: x['hostName'])
YamlUtil().dump_file(yml, args.output)

通用排序改造方案

在原有YamlUtil类中新增通用排序方法,支持指定任意层级的数组路径、自定义排序规则、升降序配置:

from typing import List, Any, Callable, Optional

class YamlUtil:
    # 原有代码保持不变,新增以下方法
    def sort_sequence(self, data: dict, key_path: List[str], sort_key: Optional[Callable] = None, reverse: bool = False) -> dict:
        """
        对YAML数据中指定路径下的数组进行排序
        :param data: 加载后的YAML数据对象
        :param key_path: 要排序的数组所在的键路径,比如要排序根节点下的devices就传['devices']
        :param sort_key: 排序用的key函数,和Python内置sort的key参数用法一致
        :param reverse: 是否降序,默认False为升序
        :return: 排序后的数据对象
        """
        # 逐层定位到要排序的数组对象
        current = data
        for key in key_path:
            if key not in current:
                raise KeyError(f"指定的路径{key_path}在数据中不存在,异常位置:{key}")
            current = current[key]
        if not isinstance(current, list):
            raise TypeError(f"指定路径{key_path}对应的内容不是数组,无法排序")
        # 执行排序
        current.sort(key=sort_key, reverse=reverse)
        return data

通用方法使用示例

原有按hostName升序排序场景

yml_util = YamlUtil()
yml_data = yml_util.load_file(args.input)
yml_util.sort_sequence(yml_data, key_path=['devices'], sort_key=lambda x: x['hostName'])
yml_util.dump_file(yml_data, args.output)

拓展场景:按hostIp降序排序

yml_util = YamlUtil()
yml_data = yml_util.load_file(args.input)
yml_util.sort_sequence(yml_data, key_path=['devices'], sort_key=lambda x: x['hostIp'], reverse=True)
yml_util.dump_file(yml_data, args.output)

注意事项

基于ruamel.yaml的rt(往返)模式实现,排序操作不会破坏原有YAML文件的注释、缩进、引号等格式配置,和原有逻辑完全兼容。

内容的提问来源于stack exchange,提问作者senthilkumar S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:57:04