python - Python:如何有效地将 4 个字典列表嵌套到一个中?
问题描述
我有一个 MSSQL 存储过程,它返回 4 个选项给我:Entities
、Certificates
和. 我需要在 Pyton 中将这 4 个选项组合在一起,我将所有选项放在了它们的. 这些选择中的每一个都有一个我可以用于合并。Contacts
Logs
Entities
Contacts
Logs
Certificate
EntityId
输入是简单的基本数据类列表,其中包含来自 SQL 的信息。我们将这些数据类转换为合并函数内的字典。
当我最初编写代码时,我不知道选择可能非常大(Certificates
包括所有其他记录的 100.000 个)。不幸的是,由于循环内列表推导的许多不必要的迭代,这使得下面的代码非常低效。最多可能需要 70 秒。我确信有一种方法可以使这更快。如何提高性能以尽可能高效?
from dataclasses import asdict
def cert_and_details(entities: List[Entity],
certificates: List[Certificate],
req_logs: List[DocumentRequestHistory],
recipients: List[Recipient]) -> List[dict]:
entities = [asdict(ent) for ent in entities]
certificates = [asdict(cert) for cert in certificates]
req_logs = [asdict(log) for log in req_logs]
recipients = [asdict(rec) for rec in recipients]
results = []
for cert_dict in certificates:
cert_entity_id = cert_dict["entityid"]
logs_under_cert = [log for log in req_logs if log["entityid"] == cert_entity_id]
cert_dict["logs"] = logs_under_cert
entities_under_cert = [ent for ent in entities if ent["entityid"] == cert_entity_id]
cert_dict["linkedentity"] = entities_under_cert
recipients_under_cert = [rec for rec in recipients if rec["entityid"] == cert_entity_id]
cert_dict["recipients"] = recipients_under_cert
results.append(cert_dict)
return results
解决方案
提供的代码的主要问题是它的计算复杂性:它运行在O(C * (L + E + R))
证书C
数量L
、日志E
数量、实体R
数量和接收者数量的位置。如果很小,这很好L+E+R
,但如果不是这种情况,那么代码会很慢。
您可以编写一个O(C + L + E + R)
及时运行的实现。这个想法是首先建立一个索引,以按实体 ID 对日志/实体/收件人进行分组。这是一个简短的例子:
# Note: defaultdict should help to make this code smaller (and possibly faster)
logIndex = dict()
for log in req_logs:
entityId = log["entityid"]
if entityId in logIndex:
logIndex[entityId].append(log)
else:
logIndex[entityId] = [log]
此代码在 (amortized) 中运行O(L)
。然后,您可以使用仅检索req_log
具有给定实体 ID 的所有项目logIndex[entityId]
。
提供的代码中还有另一个问题:字典列表效率低下:字典索引很慢,字典也不是内存效率。存储和计算数据的更好方法是使用数据帧(例如,使用也提供相对优化功能的Pandasgroupby
)。
推荐阅读
- python - 如何使用opencv获取轮廓作为图像
- python-3.x - 在 python 中导入包时遇到问题
- postgresql - 将记录从一个表插入到另一个表,然后删除插入的记录
- delphi - 如何在不重新安装整个 JVCL 库的情况下修复 JvYearGrid 控件的小错误
- python - 返回 2 个或更多 dfs 的函数 - 如何在 main() 函数中调用它?
- python - 如何使用 Python 操作 CSV 中特定索引中的所有项目?
- python - 使用空格分隔符连接多个 numpy 字符串数组
- javascript - 无法在 express 和 Mongodb 中填充字段
- javascript - JavaScript String Function charAt() 可以查找多个字符吗?
- azure-devops - 从 React 应用程序创建 Azure Devops Web 扩展