讲师中心 微信公众号
AI工具推荐 视频效率加速

使用 Python 识别 YAML 文件中指定键值对的重复项

浅浩同学_1080

浅浩同学_1080

发布时间:2025-12-05 10:09:28

|

610人浏览过

|

来源于php中文网

原创

使用 Python 识别 YAML 文件中指定键值对的重复项

本文详细介绍了如何使用 python 和 `pyyaml` 库高效地查找 yaml 文件中符合特定条件的重复条目。我们将专注于识别那些不仅主键(如 ip 地址)相同,而且关联属性(如类型)也完全一致的数据记录,通过构建一个映射表来追踪并报告这些重复项。

理解重复项的定义

在处理结构化数据时,"重复项"的定义至关重要。在本教程中,我们面临的挑战是识别 YAML 文件中的数据条目,这些条目不仅在一个特定字段(例如 ip 地址)上相同,而且在另一个关联字段(例如 type)上也必须完全一致。例如,如果 1.1.1.1 既有 typeA 又有 typeB,这不被视为重复;但如果 1.1.1.1 两次都关联 typeA,则应标记为重复。

环境准备

要开始处理 YAML 文件,我们需要安装 pyyaml 库。这是一个功能强大且广泛使用的 Python 库,用于解析和生成 YAML 数据。

pip install pyyaml

核心逻辑实现

识别这类重复项的核心思路是遍历 YAML 文件中的每个条目,并维护一个映射表来记录我们已经遇到的 ip 和 type 组合。当遇到一个新的条目时,我们检查其 ip 是否已经在映射表中,并且其 type 是否与映射表中记录的 ip 对应的 type 相同。

以下是实现此功能的 Python 脚本:

Expanso json-flatten
Expanso json-flatten

通过 CLI 或 MCP 服务器,使用 Expanso Edge 管道扁平化嵌套 JSON 对象。

下载

立即学习“Python免费学习笔记(深入)”;

import yaml
from collections import defaultdict

def find_duplicate_ip_types(yaml_file_path):
    """
    查找 YAML 文件中 IP 地址和类型都相同的重复条目。

    Args:
        yaml_file_path (str): YAML 文件的路径。

    Returns:
        list: 包含重复 IP 和类型的字符串列表。
    """
    try:
        with open(yaml_file_path, 'r', encoding='utf-8') as file:
            data = yaml.safe_load(file)
    except FileNotFoundError:
        print(f"错误:文件 '{yaml_file_path}' 未找到。")
        return []
    except yaml.YAMLError as e:
        print(f"错误:解析 YAML 文件时发生错误:{e}")
        return []

    # 确保 YAML 文件的根节点是一个列表,否则可能无法按预期处理
    if not isinstance(data, list):
        print("警告:YAML 文件根节点不是列表,可能无法按预期处理。")
        return []

    # 使用 defaultdict 存储每个 IP 出现过的类型及其计数
    # key: ip, value: {type: count}
    ip_type_counts = defaultdict(lambda: defaultdict(int))
    # 存储已识别的重复项,避免重复报告相同的 IP-Type 组合
    reported_duplicates = set()

    duplicate_entries = []

    for entry in data:
        # 验证每个条目是否为字典类型
        if not isinstance(entry, dict):
            print(f"警告:YAML 条目格式不正确,跳过:{entry}")
            continue

        ip = entry.get('ip')
        entry_type = entry.get('type')

        # 检查 'ip' 或 'type' 键是否存在
        if ip is None or entry_type is None:
            print(f"警告:条目缺少 'ip' 或 'type' 键,跳过:{entry}")
            continue

        # 增加当前 IP-Type 组合的计数
        ip_type_counts[ip][entry_type] += 1

        # 如果某个 IP-Type 组合的计数大于 1,则表示有重复
        # 并且该重复项尚未被报告过,则添加到结果列表
        if ip_type_counts[ip][entry_type] > 1:
            duplicate_key = f"IP {ip}, {entry_type}"
            if duplicate_key not in reported_duplicates:
                duplicate_entries.append(f"{duplicate_key} duplicate")
                reported_duplicates.add(duplicate_key)

    return duplicate_entries

# 示例用法:
if __name__ == "__main__":
    # 创建一个示例 YAML 文件用于测试
    sample_yaml_content = """
-
    ip: 1.1.1.1
    status: Active
    type: 'typeA'
-
    ip: 1.1.1.1
    status: Disabled
    type: 'typeA'
-
    ip: 2.2.2.2
    status: Active
    type: 'typeC'
-
    ip: 3.3.3.3
    status: Active
    type: 'typeB'
-
    ip: 3.3.3.3
    status: Active
    type: 'typeC'
-
    ip: 2.2.2.2
    status: Active
    type: 'typeC'
-
    ip: 4.4.4.4
    status: Active
    type: 'typeD'
-
    ip: 4.4.4.4
    status: Inactive
    type: 'typeD'
-
    """
    yaml_filename = 'myyaml.yaml'
    with open(yaml_filename, 'w', encoding='utf-8') as f:
        f.write(sample_yaml_content)

    print(f"正在分析文件: {yaml_filename}")
    duplicates = find_duplicate_ip_types(yaml_filename)

    if duplicates:
        print("\n发现的符合条件的重复项:")
        for dup in duplicates:
            print(dup)
    else:
        print("\n未发现符合条件的重复项。")

代码解析

  1. 导入模块:

    • yaml: 用于解析和加载 YAML 文件。yaml.safe_load() 是推荐的加载方式,可以防止潜在的安全问题。
    • collections.defaultdict: 用于创建嵌套字典,方便地为不存在的键自动创建默认值(这里是另一个 defaultdict(int)),从而简化计数逻辑。
  2. find_duplicate_ip_types 函数:

    • 文件加载与错误处理: 使用 with open(...) 安全地打开并读取 YAML 文件,并指定 encoding='utf-8' 以处理各种字符编码。通过 try-except 块捕获 FileNotFoundError(文件不存在)和 yaml.YAMLError(YAML 格式错误),增强了脚本的健壮性。
    • 根节点类型检查: 验证 YAML 文件的根节点是否为列表。如果不是,则可能不符合预期的处理结构。
    • 数据结构:
      • ip_type_counts = defaultdict(lambda: defaultdict(int)): 这是核心数据结构。它是一个嵌套的 defaultdict。外层键是 ip 地址,其值是另一个 defaultdict(int),内层键是 type,内层值是该 ip 和 type 组合出现的次数。
      • reported_duplicates = set(): 这个集合用于存储已经报告过的重复项的字符串表示(例如 "IP 1.1.1.1, typeA"),目的是确保每个唯一的重复组合只被报告一次,避免重复输出。
    • 遍历与计数: 脚本遍历 YAML 数据中的每个条目。对于每个条目,它首先验证其是否为字典类型,然后安全地提取 ip 和 type 键的值,使用 entry.get() 方法避免因键不存在而引发 KeyError。
    • 条件检查与报告: ip_type_counts[ip][entry_type] += 1 每次遇到一个 ip-type 组合就增加其计数。如果某个组合的计数 > 1,则说明这是一个重复项。此时,脚本会检查 reported_duplicates 集合,如果该重复项尚未被报告,则将其添加到 duplicate_entries 列表中并更新 reported_duplicates 集合。
    • 返回结果: 函数返回一个包含所有符合条件的重复项描述的列表。
  3. 示例用法 (if __name__ == "__main__":): 这部分代码展示了如何调用 find_duplicate_ip_types 函数。它首先创建一个临时的 myyaml.yaml 文件,其中包含示例数据,然后调用函数进行分析,并打印出发现的重复项。这使得整个脚本可以独立运行并验证其功能。

注意事项与扩展

  • 健壮性与输入验证: 虽然脚本已经包含了文件和 YAML 解析的异常处理,但对于生产环境,可能还需要对 ip 和 type 的数据类型进行更严格的验证(例如,确保 ip 是有效的 IP 地址格式,type 是预期的字符串)。
  • 性能优化: 对于非常大的 YAML 文件(例如,GB 级别),一次性加载整个文件到内存可能会导致内存溢出。在这种情况下,可以考虑使用流式解析库或分块读取文件,但对于大多数常见的 YAML 文件大小,当前的方法是高效且易于理解的。
  • 自定义重复规则: 如果需要根据更多键(例如 ip, type, status 都相同才算重复),只需修改 ip_type_counts 的键结构。例如,可以使用元组 (ip, entry_type, status) 作为 ip_type_counts 的键。
  • 输出格式: 当前输出是简单的字符串列表。在实际应用中,你可能希望将重复项以更结构化的方式(如 JSON、CSV 或更复杂的 Python 对象)返回,以便后续的数据处理或报告。

总结

本教程提供了一个使用 Python 和 pyyaml 库查找 YAML 文件中特定键值对重复项的完整解决方案。通过维护一个 defaultdict 来高效地跟踪 ip 和 type 的组合计数,并结合 set 来避免重复报告,我们能够准确地识别出符合复杂重复定义的数据。这种方法不仅灵活,而且具有良好的可读性和可维护性,是处理类似数据验证任务的有效工具。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2215

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3522

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1176

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4059

2025.09.10

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3211

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

554

2025.10.31

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

542

2026.02.12

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1818

2023.08.03

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn