在数据处理的实际场景中,我们经常会遇到需要从多个数据源中整合信息的情况。假设我们有以下三组数据,它们都以字典列表的形式存储:
listA: 包含名称及其对应的原始名称信息。
listA = [ {"name": "name sample 1", "original_name": "original name sample 1"}, {"name": "name sample 2", "original_name": "original name sample 2"}, # ... 更多数据 ]
listB: 包含地址及其对应的原始地址信息。
listB = [ {"address": "address sample 1", "original_address": "original address sample 1"}, {"address": "address sample 2", "original_address": "original address sample 2"}, # ... 更多数据 ]
dataList: 我们的主数据列表,包含ID、创建时间、名称和地址。
立即学习“Python免费学习笔记(深入)”;
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 的内容,并通过匹配 name 字段从 listA 中获取 original_name,以及通过匹配 address 字段从 listB 中获取 original_address,最终的 finalList 结构应如下所示:
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", }, # ... ]
初学者可能会尝试使用多层嵌套循环来解决这个问题,例如:
# 示例:仅处理 original_name 的嵌套循环尝试 finalList_partial = [] for data in dataList: found_name = False for item_a in listA: if "name" in data and data["name"] == item_a["name"]: new_entry = { "id": data["id"], "created_at": data["created_at"], "name": data["name"], "original_name": item_a["original_name"], "address": data["address"], # 注意:这里还没有 original_address } finalList_partial.append(new_entry) found_name = True break # 找到匹配项后跳出内层循环 if not found_name: # 如果没有找到匹配的name,也要添加原始数据 finalList_partial.append(data.copy()) # 复制原始字典
这种方法虽然可以实现部分功能,但存在明显的问题:
为了解决上述问题,我们可以采用一种更高效且更具可扩展性的方法:将辅助列表转换为查找字典(哈希表)。字典的平均查找时间复杂度为 O(1),这能显著提高数据匹配的效率。
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"}, {"name": "name sample 3", "original_name": "original name sample 3"}, # 增加一个未在dataList中匹配的示例 ] listB = [ {"address": "address sample 1", "original_address": "original address sample 1"}, {"address": "address sample 2", "original_address": "original address sample 2"}, {"address": "address sample 3", "original_address": "original address sample 3"}, # 增加一个未在dataList中匹配的示例 ] 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"}, {"id": "3", "created_at": "date 3", "name": "name sample 3", "address": "address sample 4"}, # name匹配,address不匹配 {"id": "4", "created_at": "date 4", "name": "name sample 4", "address": "address sample 3"}, # address匹配,name不匹配 {"id": "5", "created_at": "date 5", "name": "name sample 5", "address": "address sample 5"}, # 均不匹配 ] # 1. 创建查找字典以提高效率 # name_lookup: {"name sample 1": "original name sample 1", ...} name_lookup = {item["name"]: item["original_name"] for item in listA} # address_lookup: {"address sample 1": "original address sample 1", ...} address_lookup = {item["address"]: item["original_address"] for item in listB} # 2. 深度复制dataList以避免修改原始数据 finalList = deepcopy(dataList) # 3. 遍历finalList并添加匹配的数据 for item in finalList: # 尝试根据name查找original_name if "name" in item and item["name"] in name_lookup: item["original_name"] = name_lookup[item["name"]] # 尝试根据address查找original_address if "address" in item and item["address"] in address_lookup: item["original_address"] = address_lookup[item["address"]] print("原始 dataList:") import json print(json.dumps(dataList, indent=4, ensure_ascii=False)) print("\n合并后的 finalList:") print(json.dumps(finalList, indent=4, ensure_ascii=False))
from copy import deepcopy: 导入 deepcopy 函数。这是至关重要的一步,它确保我们创建 dataList 的一个完全独立的副本。如果直接使用 finalList = dataList,那么 finalList 和 dataList 将指向同一个内存地址,对 finalList 的修改会直接影响 dataList。deepcopy 创建了一个全新的、独立的列表及其内部所有字典的副本。
创建查找字典:
name_lookup = {item["name"]: item["original_name"] for item in listA} address_lookup = {item["address"]: item["original_address"] for item in listB}
这两行代码使用字典推导式(Dictionary Comprehension)高效地构建了两个查找字典。例如,name_lookup 会将 listA 中每个字典的 name 值作为键,对应的 original_name 值作为字典的值。这种预处理步骤使得后续的查找操作非常快速。
遍历并合并数据:
for item in finalList: if "name" in item and item["name"] in name_lookup: item["original_name"] = name_lookup[item["name"]] if "address" in item and item["address"] in address_lookup: item["original_address"] = address_lookup[item["address"]]
我们遍历 finalList 中的每一个字典 item。在添加新字段之前,进行双重检查:
性能考量: 当 listA、listB 或 dataList 的数据量非常大时,使用查找字典的方法能够提供显著的性能提升。其整体时间复杂度为 O(len(listA) + len(listB) + len(dataList)),远优于多层嵌套循环的 O(N*M)。
数据完整性与缺失值处理:
item["original_name"] = name_lookup.get(item.get("name"), None) # 如果name键不存在或匹配不到,则为None item["original_address"] = address_lookup.get(item.get("address"), None)
这里 item.get("name") 用于安全地获取 name 键的值,即使 name 键本身不存在也不会报错。
内存使用: deepcopy 会创建一份完整的副本,这会增加内存消耗。对于极大的数据集,如果允许修改原始 dataList,可以省略 deepcopy,直接在 dataList 上进行操作,但这通常不推荐,因为它会改变原始数据。
可读性与维护性: 将数据合并逻辑封装成函数可以提高代码的可读性和复用性,例如:
def merge_data_lists(data_list, lookup_list_a, lookup_key_a, value_key_a, lookup_list_b, lookup_key_b, value_key_b): name_lookup = {item[lookup_key_a]: item[value_key_a] for item in lookup_list_a} address_lookup = {item[lookup_key_b]: item[value_key_b] for item in lookup_list_b} merged_list = deepcopy(data_list) for item in merged_list: if lookup_key_a in item and item[lookup_key_a] in name_lookup: item[value_key_a] = name_lookup[item[lookup_key_a]] if lookup_key_b in item and item[lookup_key_b] in address_lookup: item[value_key_b] = address_lookup[item[lookup_key_b]] return merged_list # 使用示例 # final_data = merge_data_lists(dataList, listA, "name", "original_name", listB, "address", "original_address")
这种函数化处理能够更好地适应更复杂的合并需求。
在Python中处理字典列表的合并与扩展任务时,将辅助数据转换为查找字典(哈希表)是一种高效且健壮的策略。它不仅能够显著提升处理大规模数据集的性能,还能使代码逻辑更加清晰、易于维护和扩展。通过合理运用 deepcopy 和条件查找,我们可以确保数据处理的准确性,并灵活应对各种数据匹配场景。
以上就是Python中基于键值匹配合并与扩展字典列表的实用指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号