Python循环中高效切片列表/移除已处理数据的优化方案求助
Python循环中高效切片列表/移除已处理数据的优化方案求助
看起来你现在的核心问题是反复遍历大列表+低效的已处理项移除,导致整体运行速度拉胯。咱们先拆解下当前代码的性能瓶颈,再给出针对性的优化方案。
当前代码的性能痛点
- 双重循环+
lead not in processed检查:in操作对列表是O(n)复杂度,再加上每次用列表推导式遍历整个hunter_results,这部分的时间复杂度直接飙升到O(n²),3000+数据量的情况下,开销会指数级增长。 - 每次处理完一个admin就修改原列表,后续循环还要重复遍历缩小后的列表,本质上是在重复做分组的无用功。
最优优化思路:先分组,再处理
核心逻辑是只遍历一次hunter_results,按admin.slug提前完成分组,之后直接按组给对应的admin处理,完全不需要反复遍历或移除元素。这种方式的时间复杂度是O(n)(分组)+O(m)(遍历admin+处理),比原代码高效太多。
优化后的代码示例
from collections import defaultdict ADMINS = admins.get_admins() lead_list_ids = get_lead_list_ids(TAG) # 返回admin.slug与list id的映射字典 # 第一步:一次性按slug分组所有leads,仅遍历一次hunter_results lead_groups = defaultdict(list) for lead in hunter_results: # 提取邮箱前缀作为匹配的slug slug = lead.account.owner.email.split('@')[0] lead_groups[slug].append(lead) # 第二步:按admin处理对应分组的leads total_created = 0 for admin in tqdm(ADMINS): slug = admin.slug lead_list_id = lead_list_ids.get(slug) if not lead_list_id: continue # 无对应list id则跳过 # 获取当前admin对应的所有leads admin_leads = lead_groups.get(slug, []) if not admin_leads: continue # 处理该组leads for lead in tqdm(admin_leads): create_lead(lead, lead_list_id) total_created += 1 # 可选:清理已处理的分组,释放内存 del lead_groups[slug] print(f'\nSuccess! {total_created} leads created.')
额外性能提升点:API批量调用
如果第三方平台的API支持批量创建lead(比如一次POST多个lead对象),这会是更大的性能突破!因为网络请求的开销往往比本地代码处理大得多。比如把admin_leads打包成列表,调用类似create_leads_batch(admin_leads, lead_list_id)的批量接口,能把几十上百次请求合并成一次,速度会大幅提升。
为什么原移除方式这么慢?
你之前用hunter_results[:] = [lead for lead in hunter_results if lead not in processed],其中lead not in processed是列表的成员检查,每次都是O(k)(k为processed的长度),再加上列表推导式遍历整个hunter_results,相当于每次都要做O(n*k)的操作。随着processed越来越大,这个开销会越来越恐怖,而提前分组的方式完全避免了这种重复检查和遍历。
备注:内容来源于stack exchange,提问作者Magic-Wike
相关产品推荐
相关产品推荐

