python中集合和字典的区别 python中集合交集运算符
本文详细介绍了在Python中如何将高效包含字典的列表进行合并,特别是根据特定键(如“姓名”和“地址”)的值进行匹配,并从源列表中提取额外信息(如“来源”) al_name”和“original_address”)填充到目标列表中。教程内容从数据结构理解、初步尝试限制到优化合并策略的完整代码,并提供了示例和性能优化建议,旨在帮助开发者构建清晰结构、数据完整的复合列表。
在日常数据处理中,我们经常会遇到需要从多个数据源整合信息来构建一个更完整的数据结构的需求。例如,您可能拥有多个列表,每个列表都包含字典,而这些字典之间通过某些共同的键值存在关联。本教程将深入探讨如何地实现这一目标,特别是当需要根据键值匹配来补充或更新目标列表中的时。原始数据结构
假设我们有以下三个列表,每个列表都包含一系列字典:listA: listB: 地址包含其对应的原始地址。 dataList: 包含其对应的原始名称。 我们的主列表数据,包含ID、创建时间、名称和地址,但缺少原始名称和原始地址信息。
listA = [ { quot;namequot;: quot;名称样本1quot;, quot;original_namequot;: quot;原始名称样本1quot;, }, { quot;namequot;: quot;名称样本2quot;, quot;original_namequot;: quot;原始名称样本2quot;, } # ... 更多数据]listB = [ { quot;addressquot;: quot;地址样本1quot;, quot;original_addressquot;: quot;原始地址样本1quot;, }, { quot;addressquot;: quot;地址样本2quot;, quot;original_addressquot;: quot;原始地址样本2quot;, } # ... 更多数据]dataList = [ { quot;idquot;: quot;1quot;, quot;created_atquot;: quot;date 1quot;, quot;namequot;: quot;姓名样本 1quot;, quot;地址quot;: quot;地址样本 1quot;, }, { quot;idquot;: quot;2quot;, quot;created_atquot;: quot;日期 2quot;, quot;姓名quot;: quot;姓名样本 2quot;, quot;地址quot;: quot;地址样本 2quot;, } # ...更多数据]登录后复制目标:构建集成列表
我们的目标是创建一个新的finalList,它基于dataList,但会从listA中匹配name字段来获取original_name,并从listB中匹配address字段来获取original_address。
最终的 finalList 结构应如下所示:finalList = [ { quot;idquot;: quot;1quot;, quot;created_atquot;: quot;date 1quot;, quot;namequot;: quot;name 示例 1quot;, quot;original_namequot;: quot;original name 示例 1quot;, quot;addressquot;: quot;address 示例 1quot;, quot;original_addressquot;: quot;original address 示例 1quot;, }, { quot;idquot;: quot;2quot;, quot;created_atquot;: quot;date 2quot;, quot;namequot;: quot;name 示例 2quot;, quot;original_namequot;: quot;original name 示例 2quot;, quot;addressquot;: quot;original addressquot;: quot;原始地址样本2quot;,} # ... 更多数据]登录后复制初步尝试与呼吸
在面对此类问题时,一个常见的初步尝试是使用线圈循环进行重复和匹配。
例如,以下代码尝试从listA中获取original_name:
立即学习“Python免费学习笔记(深入)”;#假设的初步尝试#finalList = []# for datain dataList:# dataJson = {# quot;idquot;: data[quot;idquot;],# quot;created_atquot;: data[quot;created_atquot;],# quot;namequot;: data[quot;namequot;],# quot;addressquot;: data[quot;addressquot;],# }# for lista_item in listA:# if quot;namequot; in data and (data[quot;namequot;] == lista_item[quot;namequot;]):# dataJson[quot;original_namequot;] = lista_item[quot;original_namequot;]# break # 找到匹配后即可跳出内层循环# # 如何在这里同时处理# # 另一种循环 for listB_item in listB... 使代码重现复杂# FinalList.append(dataJson)登录后复制
这种方法虽然可以处理单个源列表的合并,但当需要从多个源列表(如 listA 和listB)中获取信息时,会变得非常复杂和低效。我们需要为每个独立的源列表添加一个独立的唤醒循环,这不仅增加了代码的振动性,也使得维护和扩展网格困难。高效数据合并策略
为了更加优雅和高效地解决多源列表合并问题,我们可以采用一种策略:首先复制主数据列表,然后遍历所有源数据,根据其包含的键来更新目标列表中的相应层级。1. 复制主数据列表
为了不修改原始的dataList,我们首先使用copy模块中的deepcopy函数创建一个完全独立的副本作为finalList。这样保证了对finalList的修改不会影响到dataList。from copy import deepcopy# ... (listA,listB,dataList定义同上)...finalList = deepcopy(dataList)登录后复制2. 合并源列表并迭代
将listA和listB合并成一个可迭代的序列(listA listB)。然后,我们遍历这个合并后的序列中的每一个字典条目。对于listA listB中的条目: # ...登录后复制3. 条件判断与数据更新
在遍历录入时,我们需要判断当前录入是来自listA还是listB,这可以通过检查字典中是否存在特定的键来完成(例如,"name"则存在于listA,"address"则存在来自listB)。
根据判断结果,我们再次遍历finalList,找到匹配的条目并更新其附加字段。
if quot;namequot; inentry: # 如果是来自 listA 的条目 for data in FinalList: # 遍历 FinalList 中的每个字典 if data['name'] == entry['name']: # 找到名字匹配的条目 data['original_name'] = entry['original_name'] # 添加original_name elif quot;addressquot; inentry: # 如果是来自 listB 的条目 for data in FinalList: # 执行 FinalList中的每个字典 if data['address'] == entry['address']: # 找到地址匹配的入境 data['original_address'] = entry['original_address'] # 添加original_address登录后复制
将以上步骤整合,完整示例代码如下:from copy import deepcopylistA = [ { "name": "姓名样本1", "original_name" : "原名样本1", }, { "name": "名称样本2", "original_name" : "原始名称样本2", }]listB = [ { "address": "地址样本1", "original_address" : "原始地址样本1", }, { "address": "地址样本2", "original_address" : "原始地址样本2", }]dataList = [ { "id": "1", "created_at": "日期1", "name": "名称样本1", "address": "地址样本1", }, { "id": "2", "created_at": "日期2", "name": "名称样本2", "address": "地址样本2", }]# 1. 深度复制 dataList 以创建 finalListfinalList = deepcopy(dataList)# 2. 遍历合并后的源列表 (listA 和 listB)for entry in listA listB: # 3. 根据 键判断来源并更新 FinalList if quot;namequot; in entry: # 如果是来自 listA 的边界 for data in FinalList: # 遍历 f
inalList 中的每个字典 if data['name'] == entry['name']: # 找到姓名匹配的边境 data['original_name'] = entry['original_name'] # 添加original_name elif quot;addressquot; inentry: # 如果是来自 listB 的边境 for data in FinalList: # 访问 FinalList 中的每个字典 if data['address'] == entry['address']: # 找到地址匹配的边界 data['original_address'] = entry['original_address'] # 添加original_addressprint("原始 dataList (补充):")print(dataList)print("\n最终合并后的 FinalList:")print(finalList)登录后复制运行结果
执行上述代码,您将得到如下输出:原始 dataList (补充修改):[ { 'id': '1', 'created_at': '日期1', '姓名':'姓名样本1', 'address': '地址样本1' }, { 'id': '2', 'created_at': '日期2', 'name': '名称样本2', 'address': '地址样本2' }]最终合并后的finalList:[ { 'id': '1', 'created_at': '日期1', 'name': '名称样本1', 'address': '地址样本1', 'original_name': '原始名称样本1', 'original_address': '原始地址样本1' }, { 'id': '2', 'created_at': '日期2', 'name': '名称样本2', 'address': '地址样本2', 'original_name': '原始名称样本2', 'original_address': '原始地址样本2' }]登录后复制注意事项与性能优化
deepcopy的必要性:如果不使用deepcopy而直接finalList = dataList,那么finalList将只是
dataList 的一个引用。对 FinalList 的任何修改都会直接反映在 dataList 上。使用 deepcopy 保证我们的操作是一个完全独立的数据副本。
数据量考量与性能优化:数据量考量与性能优化:查询方案对于数据量不大的情况是有效且容易理解的。然而,当 listA、listB 或 dataList 的规模非常大时,渲染循环(对于 listA 中的条目 listB 内部的对于 FinalList 中的数据)会导致 O(N*M)的时间复杂度,其中N是listA和listB的总长度,M是dataList的长度。这在大型数据集上可能会非常慢。
优化方案:预先将listA和listB转换为字典(大概映射),以实现O(1)的平均查找时间。然后,只需简化finalList一次,即可完成数据填充。from copy import deepcopy# ... (listA, listB, dataList定义同上) ...#构建分区映射name_map = {item[quot;namequot;]: item[quot;original_namequot;] for item in listA}address_map = {item[quot;addressquot;]: item[quot;original_addressquot;] for item in listB}finalList_optimized = deepcopy(dataList)for data in FinalList_optimized: # 从 name_map 中查找并添加original_name if data['name'] in name_map: data['original_name'] = name_map[data['name']] # 从address_map中查找并添加original_address if data['address'] in address_map: data['original_address'] = address_map[data['address']]print(quot;\n优化后的finalList:quot;)print(finalList_optimized)登录后复制
这种优化方案的时间复杂度将变为O(N M),其中N是源列表的总长度(用于构建映射),M 是 dataList 的长度(用于查找和查找),显着提高了大数据集处理的效率。
处理数据不匹配的情况:在实际应用中,dataList中的名称或地址可能在listA或listB中找到匹配项。上述代码在查找匹配时不会添加original_name或original_address字段。如果需要为这些情况设置默认值或特殊处理,可以在if data['key'] in map:块的else分支中进行处理。总结
本教程详细介绍了如何在Python中根据键值匹配,将多个列表中的字典数据合并到一个新的复合列表中。
我们从理解原始问题和初步尝试的局限性出发,逐步构建了一个清晰、可维护的解决方案。对于小规模数据,直接进行损伤循环的方法简单易行;而对于大规模数据集,通过构建间歇映射(字典)进行,可以显着提升数据合并的效率。选择哪一个掌握这些技巧将有助于您更高效地处理和集成复杂的数据结构。
以上就是Python中基于键值匹配合并多列表数据的策略的详细内容,更多请关注乐哥常识网其他相关文章!