0

0

使用 Python 查找 YAML 文件中特定键值对的重复项

碧海醫心

碧海醫心

发布时间:2025-12-05 11:48:07

|

278人浏览过

|

来源于php中文网

原创

使用 Python 查找 YAML 文件中特定键值对的重复项

本文将指导您如何使用 python 和 pyyaml 库,高效地识别 yaml 文件中具有相同 ip 地址和相同类型的重复条目。通过构建一个 ip-类型映射,您可以遍历数据并准确地检测并报告符合特定条件的重复项,从而优化您的数据校验流程。

在处理配置或数据清单时,YAML 文件因其简洁性和可读性而广受欢迎。然而,随着文件规模的增长,识别其中是否存在特定条件的重复数据变得至关重要,例如查找具有相同 IP 地址且类型也相同的重复条目。本教程将详细介绍如何使用 Python 编写脚本来自动化这一过程。

准备工作

在开始之前,您需要确保系统中安装了 pyyaml 库,它是 Python 处理 YAML 文件的标准库。如果尚未安装,可以通过 pip 命令进行安装:

pip install pyyaml

理解目标与数据结构

我们的目标是从一个 YAML 文件中识别出满足以下条件的重复条目:

  1. 条目中包含 ip 键和 type 键。
  2. 存在多个条目具有相同的 ip 值。
  3. 这些具有相同 ip 值的条目,其 type 值也必须相同。

考虑以下 YAML 数据示例:

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

-
    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'

根据上述规则:

Civitai
Civitai

AI艺术分享平台!海量SD资源和开源模型。

下载
  • IP 1.1.1.1 有两个条目,它们的 type 都是 typeA,因此被视为重复。
  • IP 2.2.2.2 有两个条目,它们的 type 都是 typeC,因此被视为重复。
  • IP 3.3.3.3 有两个条目,但它们的 type 分别是 typeB 和 typeC,不满足 type 也相同的条件,因此不被视为重复。

期望的输出是:

IP 1.1.1.1, typeA duplicate
IP 2.2.2.2, typeC duplicate

核心逻辑与实现

要实现这一目标,我们可以采用一种基于哈希表(Python 中的字典)的策略。我们将遍历 YAML 文件中的每一个条目,并记录每个 ip 第一次出现的 type。当再次遇到相同的 ip 时,我们将检查其 type 是否与之前记录的 type 相同。

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

import yaml

def find_duplicated_ip_types(yaml_file_path):
    """
    查找 YAML 文件中具有相同 IP 和相同类型的重复条目。

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

    Returns:
        list: 包含重复条目描述的列表,例如 ["IP 1.1.1.1, typeA duplicate"]。
    """
    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 []

    # 用于存储首次遇到的 IP 及其对应的类型
    # 格式为 {ip: type}
    ip_type_map = {}

    # 用于存储已识别的重复项,避免重复报告
    reported_duplicates = set()

    duplicates_found = []

    if not isinstance(data, list):
        print("警告:YAML 文件根元素不是列表,可能无法按预期处理。")
        return []

    for entry in data:
        # 确保 entry 是一个字典且包含 'ip' 和 'type' 键
        if isinstance(entry, dict) and 'ip' in entry and 'type' in entry:
            ip = entry['ip']
            entry_type = entry['type']

            # 检查当前 IP-类型组合是否已在 map 中
            if ip in ip_type_map:
                # 如果 IP 存在,并且其记录的类型与当前条目类型相同,则为重复项
                if entry_type == ip_type_map[ip]:
                    duplicate_key = f"{ip}-{entry_type}"
                    if duplicate_key not in reported_duplicates:
                        duplicates_found.append(f"IP {ip}, {entry_type} duplicate")
                        reported_duplicates.add(duplicate_key)
                # 如果 IP 存在但类型不同,则更新 map 为当前类型 (这表示该 IP 有多个类型,不构成我们定义的重复)
                # 或者可以根据需求选择不更新,保持第一次遇到的类型
                # 在本场景中,如果 IP 存在但类型不同,它不是我们寻找的重复,所以不需要特别处理 map
            else:
                # 如果是第一次遇到这个 IP,则将其 IP 和类型添加到 map 中
                ip_type_map[ip] = entry_type
        else:
            # 打印警告信息,指出 YAML 数据中存在无效条目
            # 在生产环境中,可以考虑记录日志或抛出异常
            print(f"警告:YAML 数据中存在无效条目或缺少 'ip'/'type' 键:{entry}")

    return duplicates_found

# 示例用法
yaml_file = 'myyaml.yaml' # 替换为您的 YAML 文件路径
results = find_duplicated_ip_types(yaml_file)

if results:
    print("\n发现以下重复条目:")
    for res in results:
        print(res)
else:
    print("\n未发现符合条件的重复条目。")

代码解析

  1. 导入 yaml 库: import yaml 引入处理 YAML 文件所需的模块。
  2. 文件读取与加载:
    • with open(yaml_file_path, 'r', encoding='utf-8') as file: 安全地打开 YAML 文件。
    • data = yaml.safe_load(file) 使用 yaml.safe_load() 方法加载 YAML 数据。safe_load 比 load 更安全,因为它只解析标准 YAML 标签,避免了潜在的任意代码执行风险。
    • 增加了 try-except 块来处理文件未找到 (FileNotFoundError) 和 YAML 解析错误 (yaml.YAMLError) 的情况,提高了脚本的健壮性。
  3. 初始化映射和结果列表:
    • ip_type_map = {}: 这是一个字典,用于存储每个 ip 第一次出现时对应的 type。键是 ip 地址,值是其 type。
    • reported_duplicates = set(): 这是一个集合,用于存储已经报告过的重复项的唯一标识(例如 "1.1.1.1-typeA"),目的是防止同一个重复组合被多次报告。
    • duplicates_found = []: 这是一个列表,用于收集所有符合条件的重复项的描述字符串。
  4. 遍历数据:
    • if not isinstance(data, list): 检查 YAML 文件的根元素是否为列表,因为我们的预期数据结构是一个列表。
    • for entry in data: 脚本遍历 YAML 文件加载后的数据列表中的每一个字典(即每一个条目)。
  5. 条件判断与逻辑处理:
    • if isinstance(entry, dict) and 'ip' in entry and 'type' in entry: 这一行确保当前处理的 entry 是一个有效的字典,并且包含我们感兴趣的 ip 和 type 键。如果缺少这些键,会打印警告信息。
    • ip = entry['ip'] 和 entry_type = entry['type'] 提取当前条目的 IP 和类型。
    • if ip in ip_type_map: 检查当前的 ip 是否已经在 ip_type_map 中出现过。
      • if entry_type == ip_type_map[ip]: 如果 ip 已经存在,并且当前条目的 type 与 ip_type_map 中记录的 type 相同,则说明找到了一个符合条件的重复项。
        • duplicate_key = f"{ip}-{entry_type}" 创建一个唯一的键来标识这个 IP-类型组合。
        • if duplicate_key not in reported_duplicates: 检查这个重复组合是否已经报告过。
        • duplicates_found.append(...) 将重复项的描述添加到结果列表。
        • reported_duplicates.add(duplicate_key) 将此重复组合添加到已报告集合中,防止重复报告。
    • else: 如果 ip 是第一次出现,则将其 ip 和 type 添加到 ip_type_map 中。

注意事项与扩展

  1. 错误处理: 示例代码中包含了对文件不存在和 YAML 解析错误的捕获。在实际应用中,您可能需要更详细的错误日志记录机制。
  2. 数据完整性: 脚本会检查每个条目是否为字典以及是否包含 ip 和 type 键。对于不符合预期格式的条目,会输出警告。根据需求,您可以选择跳过这些条目,或者抛出异常。
  3. 性能优化: 对于非常大的 YAML 文件,如果数据量达到百万级别,可以考虑使用更高效的数据结构或分块处理策略,尽管对于大多数常规用途,当前字典查找的效率已经足够高。
  4. 输出格式定制: 当前脚本将重复项打印到控制台。您可以修改 duplicates_found.append() 部分,将结果保存到文件、数据库,或者以 JSON 等其他格式返回。
  5. 更复杂的重复定义: 如果重复的定义有所不同(例如,只关心 IP 重复,不关心类型,或者关心 IP 和状态的组合),只需调整 ip_type_map 的键和值,以及比较逻辑即可。
  6. yaml.safe_load() 的重要性: 始终推荐使用 safe_load() 而非 load(),以避免加载恶意构造的 YAML 文件时可能带来的安全风险。

总结

通过本教程,您学会了如何利用 Python 和 pyyaml 库来高效地识别 YAML 文件中具有特定条件的重复数据。这种方法不仅适用于 IP 地址和类型,还可以灵活应用于其他键值对的组合,为数据校验和清理提供了强大的工具。掌握这种模式,将有助于您更好地管理和维护复杂的配置和数据文件。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

765

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

640

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

619

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1285

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

549

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

709

2023.08.11

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

0

2026.01.20

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 5.7万人学习

Django 教程
Django 教程

共28课时 | 3.3万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号