
在数据处理的实际场景中,我们经常会遇到需要从多个数据源中整合信息的情况。假设我们有以下三组数据,它们都以字典列表的形式存储:
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号