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

如何在Python中遍历嵌套YAML文档并构建指定结构对象?

遍历嵌套YAML并生成指定结构的对象列表

问题背景

现有如下嵌套结构的YAML文件,需要遍历并生成包含RuleName、IgnoreList<LIST>、InputParameters<LIST>、RuleType、SubRuleType属性的对象列表:

---
InternalRuleService:
  - HomeRules:
    - RuleName: Sample1
      IgnoreList:
      InputParameters:
      - resourceId: some-res-id
      - ruleAge: 1
      - ruleAgeUnits: days
    - RuleName: Sample2
      IgnoreList:
      - Account: '12'
        Region: NorthAmericas
      - Account: '10'
        Region: AsiaPacific
      - Account: '10'
        Region: Europe
      InputParameters:
      - InterfaceIds: xxxx1,xxxxx2
    - RuleName: Sample3
      IgnoreList:
      - Account: '14'
        Region: NorthAmericas
      - Account: '18'
        Region: MiddleEast
      InputParameters:
      - localContact: JohnDoe
        contactNumber: 123123 
  - CustomRules:
    - RuleName: CustomOne
      documentType: packet
      IgnoreList: 
      - Account: '14'
        Region: NorthAmericas
      - Account: '18'
        Region: MiddleEast
ThirdPartyRules:
  - RuleName: alta-prism
    licenseType: multi
    licenseAge: 5
    licenseAgeUnit: year
    IgnoreList: 
      - Account: '45'
        Region: NorthAmericas
      - Account: '44'
        Region: MiddleEast

之前尝试的代码仅能输出顶层键,访问子元素时出现错误:

import yaml
import json 

with open('rules.yml', 'r') as file:
   rules = yaml.safe_load(file)
    
for rows in rules:
   print(rows)

输出仅为InternalRuleService和ThirdPartyRules。

尝试访问HomeRules时:

for rows in rules:
    print(rows['HomeRules'])

报错:

TypeError: string indices must be integers

使用索引访问时:

for rows in rules:
    print(rows[0])

仅输出字符I和T。

解决方案

错误原因分析

遍历rules(字典对象)时,默认迭代的是字典的键(字符串类型),而非键对应的值,因此直接对字符串使用字典索引或列表索引会报错。需要遍历字典的键值对,逐层解析嵌套结构。

正确代码实现

以下代码会逐层遍历YAML结构,生成符合要求的对象列表(这里用字典存储每个对象,也可根据需求自定义类):

import yaml

def parse_rules(yaml_file_path):
    result = []
    with open(yaml_file_path, 'r') as file:
        rules = yaml.safe_load(file)
    
    # 遍历顶层规则类型(InternalRuleService/ThirdPartyRules)
    for rule_type, rule_data in rules.items():
        if rule_type == 'InternalRuleService':
            # 处理内部规则,包含HomeRules/CustomRules子类型
            for sub_rule_group in rule_data:
                # 每个子规则组是只有一个键值对的字典(HomeRules或CustomRules)
                sub_rule_type, rule_list = next(iter(sub_rule_group.items()))
                for rule in rule_list:
                    # 构建对象,补全默认空列表
                    rule_obj = {
                        'RuleName': rule.get('RuleName'),
                        'IgnoreList': rule.get('IgnoreList', []),
                        'InputParameters': rule.get('InputParameters', []),
                        'RuleType': rule_type,
                        'SubRuleType': sub_rule_type
                    }
                    result.append(rule_obj)
        elif rule_type == 'ThirdPartyRules':
            # 处理第三方规则,无SubRuleType
            for rule in rule_data:
                rule_obj = {
                    'RuleName': rule.get('RuleName'),
                    'IgnoreList': rule.get('IgnoreList', []),
                    'InputParameters': rule.get('InputParameters', []),
                    'RuleType': rule_type,
                    'SubRuleType': None  # 第三方规则无SubRuleType
                }
                result.append(rule_obj)
    return result

# 调用示例
if __name__ == '__main__':
    parsed_rules = parse_rules('rules.yml')
    # 打印结果验证
    for idx, obj in enumerate(parsed_rules):
        print(f"对象 {idx+1}:")
        print(obj)
        print('---')

代码说明

  1. 遍历顶层键值对:使用rules.items()获取规则类型(键)和对应的数据(值),而非仅遍历键。
  2. 区分规则类型:
    • 对于InternalRuleService,其值是一个列表,每个元素是包含HomeRules或CustomRules的字典,通过next(iter(sub_rule_group.items()))取出子规则类型和对应的规则列表。
    • 对于ThirdPartyRules,其值直接是规则列表,无需处理子类型。
  3. 补全默认值:使用dict.get()方法获取属性,当YAML中未定义IgnoreList或InputParameters时,默认返回空列表,避免出现None。
  4. 构建对象:按照需求组装每个规则对象,添加RuleType和SubRuleType属性。

输出示例

运行代码后,会生成如下结构的对象列表(示例部分输出):

对象 1:
{'RuleName': 'Sample1', 'IgnoreList': [], 'InputParameters': [{'resourceId': 'some-res-id'}, {'ruleAge': 1}, {'ruleAgeUnits': 'days'}], 'RuleType': 'InternalRuleService', 'SubRuleType': 'HomeRules'}
---
对象 2:
{'RuleName': 'Sample2', 'IgnoreList': [{'Account': '12', 'Region': 'NorthAmericas'}, {'Account': '10', 'Region': 'AsiaPacific'}, {'Account': '10', 'Region': 'Europe'}], 'InputParameters': [{'InterfaceIds': 'xxxx1,xxxxx2'}], 'RuleType': 'InternalRuleService', 'SubRuleType': 'HomeRules'}
---
对象 5:
{'RuleName': 'alta-prism', 'IgnoreList': [{'Account': '45', 'Region': 'NorthAmericas'}, {'Account': '44', 'Region': 'MiddleEast'}], 'InputParameters': [], 'RuleType': 'ThirdPartyRules', 'SubRuleType': None}
---

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:55:28