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

Python处理YAML:如何用字典替换指定字符串并解决类型报错

报错原因
  1. 你读取的YAML根节点是列表(YAML内容开头为-),并非字典类型,直接对根节点调用.items()本身就不符合数据结构逻辑。
  2. 循环内的判断逻辑写反且存在类型问题:if v in replacements是检查变量v是否为replacements字典的键,字典键必须是可哈希类型;当遍历到值为字典、列表这类不可哈希的嵌套结构时,这个判断就会抛出TypeError: unhashable type: 'dict'。你实际需要判断的是「值是否等于占位符字符串__TARGETS__」,而非判断值是否存在于替换字典的键集合中。
可运行的实现方案

你的YAML存在多层结构,且占位符位于列表内的字典字段下,需要先匹配YAML的实际结构遍历,找到值等于占位符的字段后做替换,导出YAML时指定块格式输出,避免生成行内压缩的YAML结构。

适配你给出的固定YAML结构的基础版本:

import yaml

def readYaml(path):
    with open(path, 'r', encoding='utf-8') as f:
        return yaml.safe_load(f)

yaml_data = readYaml("lib/above_Yaml.yaml")
d = {'a': [12, 23, 34]}
placeholder = '__TARGETS__'

# 遍历YAML根节点的列表元素
for node in yaml_data:
    if isinstance(node, dict):
        for key, val in node.items():
            if val == placeholder:
                node[key] = [d]

# 导出为块格式YAML
output = yaml.safe_dump(yaml_data, default_flow_style=False, allow_unicode=True)
print(output)

运行后key_001字段的输出完全匹配你的需求:

key_001:
- a:
  - 12
  - 23
  - 34

如果后续占位符可能出现在任意嵌套层级(比如嵌套在更深的字典、列表里),可以用递归替换的通用版本,不需要关心YAML具体嵌套深度:

def deep_replace(obj, placeholder, replace_value):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if v == placeholder:
                obj[k] = replace_value
            else:
                deep_replace(v, placeholder, replace_value)
    elif isinstance(obj, list):
        for idx, item in enumerate(obj):
            if item == placeholder:
                obj[idx] = replace_value
            else:
                deep_replace(item, placeholder, replace_value)
    return obj

# 调用示例
yaml_data = readYaml("lib/above_Yaml.yaml")
d = {'a': [12, 23, 34]}
yaml_data = deep_replace(yaml_data, '__TARGETS__', [d])
output = yaml.safe_dump(yaml_data, default_flow_style=False, allow_unicode=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:54:31