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)

代码解析:

sematic
sematic

一个开源的机器学习平台

下载
  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)。

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

相关专题

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

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

715

2023.06.15

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

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

625

2023.07.20

python能做什么
python能做什么

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

739

2023.07.25

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

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

617

2023.07.31

python教程
python教程

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

1235

2023.08.03

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

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

547

2023.08.04

python eval
python eval

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

575

2023.08.04

scratch和python区别
scratch和python区别

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

698

2023.08.11

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

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

精品课程

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

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

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

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