0

0

Python中基于键值匹配合并多源列表数据

DDD

DDD

发布时间:2025-07-02 21:26:15

|

744人浏览过

|

来源于php中文网

原创

python中基于键值匹配合并多源列表数据

本教程详细探讨了如何在Python中高效地将多个列表(其中包含字典对象)的数据进行合并。通过匹配特定键的值,我们将演示如何从源列表中提取所需信息,并将其整合到目标列表中,最终生成一个包含所有相关属性的统一数据结构。教程涵盖了直接循环迭代和基于字典预处理的优化方法,并提供了代码示例及性能考量。

1. 数据合并场景概述

在数据处理中,我们经常会遇到需要将分散在不同列表中的相关信息聚合到一起的场景。例如,你可能有一个主数据列表,以及多个辅助列表,这些辅助列表包含了主数据中某些字段的补充或“原始”值。我们的目标是根据共同的键(如name或address)将这些辅助信息合并到主数据项中。

假设我们有以下三组数据:

  • listA: 包含name及其对应的original_name。
  • listB: 包含address及其对应的original_address。
  • dataList: 主数据列表,包含id, created_at, name, address。
listA = [
  {
    "name": "name sample 1",
    "original_name" : "original name sample 1",
  },
  {
    "name": "name sample 2",
    "original_name" : "original name sample 2",
  }
]

listB = [
  {
    "address": "address sample 1",
    "original_address" : "original address sample 1",
  },
  {
    "address": "address sample 2",
    "original_address" : "original address sample 2",
  }
]

dataList = [
  {
    "id": "1",
    "created_at": "date 1",
    "name": "name sample 1",
    "address": "address sample 1",
  },
  {
    "id": "2",
    "created_at": "date 2",
    "name": "name sample 2",
    "address": "address sample 2",
  }
]

我们期望的最终结果finalList应该在dataList的每个字典中添加original_name和original_address字段,这些值分别来自listA和listB,通过匹配name和address键来获取。

finalList = [
  {
    "id": "1",
    "created_at": "date 1",
    "name": "name sample 1",
    "original_name" : "original name sample 1",
    "address": "address sample 1",
    "original_address" : "original address sample 1",
  },
  {
    "id": "2",
    "created_at": "date 2",
    "name": "name sample 2",
    "original_name" : "original name sample 2",
    "address": "address sample 2",
    "original_address" : "original address sample 2",
  }
]

2. 解决方案一:基于嵌套循环的直接合并

一种直观的方法是使用嵌套循环。首先,我们复制一份dataList以避免修改原始数据。然后,遍历listA和listB中的每个条目,并在finalList中查找匹配的项,找到后更新其属性。

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

from copy import deepcopy

listA = [
  {"name": "name sample 1", "original_name" : "original name sample 1"},
  {"name": "name sample 2", "original_name" : "original name sample 2"}
]

listB = [
  {"address": "address sample 1", "original_address" : "original address sample 1"},
  {"address": "address sample 2", "original_address" : "original address sample 2"}
]

dataList = [
  {"id": "1", "created_at": "date 1", "name": "name sample 1", "address": "address sample 1"},
  {"id": "2", "created_at": "date 2", "name": "name sample 2", "address": "address sample 2"}
]

finalList = deepcopy(dataList) # 使用 deepcopy 确保不影响原始 dataList

# 合并 listA 和 listB,以便一次性处理
# 这种方式会遍历 finalList 多次,效率较低,但逻辑直观
for entry in listA + listB:
    if "name" in entry: # 处理来自 listA 的数据
        for data_item in finalList:
            if data_item.get('name') == entry['name']: # 使用 .get() 避免 KeyError
                data_item['original_name'] = entry['original_name']
    elif "address" in entry: # 处理来自 listB 的数据
        for data_item in finalList:
            if data_item.get('address') == entry['address']:
                data_item['original_address'] = entry['original_address']

print("原始 dataList:", dataList)
print("合并后的 finalList:", finalList)

代码解析:

免费语音克隆
免费语音克隆

这是一个提供免费语音克隆服务的平台,用户只需上传或录制一段 5 秒以上的清晰语音样本,平台即可生成与用户声音高度一致的 AI 语音克隆。

下载
  1. from copy import deepcopy: 导入deepcopy函数,用于创建dataList的完全独立副本。这是为了确保对finalList的修改不会影响到dataList。
  2. finalList = deepcopy(dataList): 初始化finalList。
  3. for entry in listA + listB:: 将listA和listB合并成一个临时列表进行迭代。
  4. if "name" in entry: 和 elif "address" in entry:: 根据entry中存在的键来判断它来自listA还是listB,并执行相应的匹配和赋值操作。
  5. 内层循环 for data_item in finalList:: 遍历finalList中的每个字典,查找匹配的name或address。
  6. data_item.get('name') == entry['name']: 使用.get()方法访问键,可以避免在键不存在时抛出KeyError,使代码更健壮。

注意事项: 这种方法在数据量较小时易于理解和实现。然而,其时间复杂度较高。如果dataList有N个元素,listA有M个元素,listB有P个元素,那么查找和更新original_name的操作是M * N,查找和更新original_address的操作是P * N。总时间复杂度近似为 O((M+P)*N),在大规模数据处理时效率低下。

3. 解决方案二:利用字典预处理优化合并效率

为了提高效率,特别是当listA、listB或dataList的数据量较大时,我们可以利用哈希表的O(1)平均查找时间特性。核心思想是将listA和listB预处理成字典(哈希表),以name和address作为键,方便快速查找对应的original_name和original_address。

from copy import deepcopy

listA = [
  {"name": "name sample 1", "original_name" : "original name sample 1"},
  {"name": "name sample 2", "original_name" : "original name sample 2"}
]

listB = [
  {"address": "address sample 1", "original_address" : "original address sample 1"},
  {"address": "address sample 2", "original_address" : "original address sample 2"}
]

dataList = [
  {"id": "1", "created_at": "date 1", "name": "name sample 1", "address": "address sample 1"},
  {"id": "2", "created_at": "date 2", "name": "name sample 2", "address": "address sample 2"}
]

# 1. 预处理 listA 和 listB 为字典,以便快速查找
name_map = {item['name']: item['original_name'] for item in listA}
address_map = {item['address']: item['original_address'] for item in listB}

# 2. 创建 finalList 的副本
finalList = deepcopy(dataList)

# 3. 遍历 finalList,根据映射关系添加新字段
for data_item in finalList:
    # 查找并添加 original_name
    name_key = data_item.get('name')
    if name_key in name_map:
        data_item['original_name'] = name_map[name_key]
    # else: 可以选择处理未找到匹配的情况,例如设置默认值或跳过

    # 查找并添加 original_address
    address_key = data_item.get('address')
    if address_key in address_map:
        data_item['original_address'] = address_map[address_key]
    # else: 可以选择处理未找到匹配的情况

print("原始 dataList:", dataList)
print("优化合并后的 finalList:", finalList)

代码解析:

  1. 预处理映射表:
    • name_map = {item['name']: item['original_name'] for item in listA}: 使用字典推导式将listA转换为一个字典name_map,其中键是name,值是original_name。
    • address_map = {item['address']: item['original_address'] for item in listB}: 同样地,将listB转换为address_map。
    • 这一步的时间复杂度分别为O(M)和O(P)。
  2. 遍历主列表并合并:
    • for data_item in finalList:: 只需遍历finalList一次。
    • name_key = data_item.get('name'): 获取当前数据项的name值。
    • if name_key in name_map:: 在name_map中进行O(1)查找。如果找到,则将对应的original_name添加到data_item中。
    • 对address进行类似操作。
    • 这一步的时间复杂度为O(N)。

性能优势: 这种优化方法的总时间复杂度为O(M + P + N),远优于嵌套循环的O((M+P)*N),尤其是在数据量大时,性能提升显著。

4. 进一步考虑与最佳实践

在实际应用中,除了上述两种方法,还需要考虑一些额外因素:

  • 键的唯一性: 上述优化方法假设listA和listB中用于匹配的键(name和address)是唯一的。如果存在重复键,字典推导式将只保留最后一个匹配项。如果需要处理非唯一键,可能需要将字典的值设为列表或其他数据结构来存储所有匹配项。
  • 缺失数据处理:
    • 如果dataList中的某个name或address在name_map或address_map中找不到匹配项,上述代码会跳过赋值。
    • 根据业务需求,你可能希望:
      • 为这些字段设置默认值(例如data_item['original_name'] = None)。
      • 记录下哪些数据项未能匹配。
      • 直接从finalList中移除未能完全匹配的项。
  • 内存使用:
    • deepcopy会创建原始列表的完整副本,这会增加内存消耗。如果原始dataList非常大且不需要保留,可以直接在dataList上进行修改,或者使用浅拷贝list(dataList)然后修改内部字典,但这需要更小心地管理引用。
    • 创建name_map和address_map也会占用额外内存,但通常是值得的,因为它们提供了显著的性能优势。
  • 代码可读性 优化后的方法虽然性能更好,但可能比简单的嵌套循环略微复杂。在选择方法时,应权衡性能需求和代码可读性。对于小规模数据,直观的嵌套循环可能更合适;对于大规模数据,预处理优化是首选。

5. 总结

本教程介绍了在Python中根据键值匹配合并多个列表数据字典的两种主要方法:

  1. 嵌套循环直接合并: 简单直观,适用于数据量较小的情况。其时间复杂度为O((M+P)*N)。
  2. 字典预处理优化合并: 通过将辅助列表转换为哈希表,显著提高查找效率,适用于大规模数据。其时间复杂度为O(M + P + N)。

在实际开发中,推荐使用字典预处理的优化方法,因为它在处理大量数据时能提供更好的性能。同时,务必考虑数据中键的唯一性、缺失数据处理以及内存消耗等因素,以构建健壮且高效的数据处理流程。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

549

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

30

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

44

2026.01.06

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

549

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

30

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

44

2026.01.06

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

9

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

22

2026.03.10

热门下载

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

精品课程

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

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

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

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