Python大字典(250k+键)的分组、统计及原键提取方案求助
问题描述
我有一个包含250k+键的大型字典,结构如下:
original_dict = { 0: ["apple", "green"], 1: ["banana", "yellow"], 2: ["apple", "red"], 3: ["apple", "brown"], 4: ["kiwi", "green"], 5: ["kiwi", "brown"], ... }
需要完成三个目标:
- 生成新字典,以列表首元素为键,对应同键的所有列表次元素组成的列表,示例:
new_dict = { "apple": ["green", "red", "brown"], "banana": ["yellow"], "kiwi": ["green", "brown"], ... }
- 统计每个键对应的元素数量,筛选出数量≥2的键,示例:
final_dict = { "apple": 3, "kiwi": 2, .... }
- 提取原字典中对应上述筛选后键的所有原键,示例:
original_keys_with_at_least_2_values = [0, 2, 3, 4, 5]
我用嵌套for循环实现时效率很低,知道Python推导式效率更高但不会用,现有代码如下:
# Create new_dict like: new_dict = {apple:None, banana:None, kiwi:None,..} new_dict = {k: None for k in original_dict.values()[0]} for k in new_dict.keys(): for i in original_dict.values()[0]: if i == k: new_dict[k] = original_dict[i][1]
高效解决方案
针对250k+规模的数据,避免嵌套循环,用一次遍历完成多步操作是最优选择,以下是具体实现:
1. 生成按首元素聚合的新字典
用collections.defaultdict可以高效完成聚合,只需遍历原字典一次:
from collections import defaultdict new_dict = defaultdict(list) for val in original_dict.values(): fruit, color = val new_dict[fruit].append(color) # 可选:转为普通字典 new_dict = dict(new_dict)
这段代码时间复杂度为O(n)(n为原字典键的数量),远优于嵌套循环的O(n²)。
2. 筛选元素数量≥2的键
用collections.Counter统计数量,再通过字典推导式筛选:
from collections import Counter # 方式1:基于已生成的new_dict统计 counts = Counter({k: len(v) for k, v in new_dict.items()}) # 方式2:第一次遍历时同步统计(更高效,避免二次遍历) # counts = Counter() # for val in original_dict.values(): # counts[val[0]] += 1 final_dict = {k: cnt for k, cnt in counts.items() if cnt >= 2}
3. 提取符合条件的原字典键
通过一次遍历原字典,结合final_dict的键筛选:
# 列表推导式简化写法 original_keys_with_at_least_2_values = [ orig_key for orig_key, val in original_dict.items() if val[0] in final_dict ]
原代码问题说明
你的现有代码存在核心逻辑错误:
original_dict.values()[0]仅取第一个值的列表,无法遍历所有元素- 嵌套循环导致时间复杂度极高,处理250k数据会异常缓慢
- 错误将value列表元素当作原字典的key去取值,逻辑完全不成立
一站式优化(单次遍历完成所有目标)
如果追求极致效率,推荐一次遍历完成三个目标,减少内存和时间开销:
from collections import defaultdict, Counter new_dict = defaultdict(list) counts = Counter() fruit_to_orig_keys = defaultdict(list) for orig_key, (fruit, color) in original_dict.items(): new_dict[fruit].append(color) counts[fruit] += 1 fruit_to_orig_keys[fruit].append(orig_key) # 生成筛选后的计数字典 final_dict = {k: cnt for k, cnt in counts.items() if cnt >= 2} # 收集所有符合条件的原键 original_keys_with_at_least_2_values = [] for fruit in final_dict: original_keys_with_at_least_2_values.extend(fruit_to_orig_keys[fruit]) # 可选:转为普通字典 new_dict = dict(new_dict)
内容的提问来源于stack exchange,提问作者Pybubb
相关产品推荐
相关产品推荐

