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

ruamel.yaml加载转储丢失重复值元素,如何配置保留?

解决思路

问题根源

核心问题不是dump阶段的配置缺失,而是加载阶段的数据丢失:

  • YAML语法中{1,1,1}表示集合(set),而Python原生set自动去重,当ruamel.yaml用typ='safe'加载时,会将这类集合解析为Python的set,重复元素在加载完成后就已被剔除,后续dump自然无法输出重复项。
  • allow_duplicate_keys配置仅针对YAML映射(键值对)中的重复键,对集合类型的重复元素无效。

解决方案

要保留重复元素,需修改数据结构或加载逻辑,以下是两种可行方案:

方案1:将集合转换为列表

既然集合无法保留重复项,可先将输入字符串中的集合语法{x,x,x}替换为列表语法[x,x,x],加载后得到Python的list即可保留重复元素:

# 修改输入处理部分
dit="{p_d:  {p: a0, nb: 0, be: {ar: {1, 1, 1, 1}}, bb: {tt: {dt: {10, 10}, vl: {0}, rl: {0}, sf: {10, 20}, ef: {10, 20}}}}}"
# 把集合的{}替换为列表的[]
yaml_str = re.sub(r'\{(\d+(?:,\s*\d+)*)\}', r'[\1]', dit)

# 后续加载和dump逻辑不变
yaml = ruamel.yaml.YAML()
yaml.default_flow_style = False
# ... 其余代码不变

dump后的输出会以列表形式保留重复元素,若需要接近原集合的格式,可额外配置列表的输出样式。

方案2:自定义集合加载器

如果必须保留类似集合的输出格式,可自定义ruamel.yaml的构造器和代表器,将YAML集合解析为允许重复的自定义容器:

from ruamel.yaml import YAML, Constructor, Representer

# 自定义允许重复的集合类
class DuplicateSet(list):
    pass

# 自定义构造器:将YAML集合解析为DuplicateSet
def construct_duplicate_set(loader, node):
    return DuplicateSet(loader.construct_sequence(node))

# 自定义代表器:将DuplicateSet输出为类似集合的格式
def represent_duplicate_set(dumper, data):
    return dumper.represent_sequence('tag:yaml.org,2002:set', data, flow_style=True)

# 注册构造器和代表器
yaml = YAML()
yaml.constructor.add_constructor('tag:yaml.org,2002:set', construct_duplicate_set)
yaml.representer.add_representer(DuplicateSet, represent_duplicate_set)

yaml.default_flow_style = False
# 后续加载和dump逻辑不变

这种方式可以在输出时保留类似集合的{}格式,同时保留重复元素。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:30:01