如何用map和lambda处理嵌套dict实现按国家日期分组过滤?
用Lambda/Map/Reduce实现嵌套字典的分组与过滤
当然可以用lambda、map配合reduce来搞定这个需求,不仅能替代可读性差的多层循环,代码逻辑还会更清晰。我先给你举个具体的例子,咱们一步步拆解实现过程:
先定义示例数据
假设你的嵌套字典结构是这样的(和你的需求匹配):
# 示例输入的嵌套字典 original_data = { "USA": { "California": { "Los Angeles": [ {"date": "2024-01-01", "value": 100}, {"date": "2024-01-02", "value": 150} ], "San Francisco": [ {"date": "2024-01-01", "value": 200}, {"date": "2024-01-02", "value": 250} ] }, "Texas": { "Houston": [ {"date": "2024-01-01", "value": 300}, {"date": "2024-01-02", "value": 350} ] } }, "Canada": { "Ontario": { "Toronto": [ {"date": "2024-01-01", "value": 400}, {"date": "2024-01-02", "value": 450} ] } } } # 需要保留的目标州集合 target_states = {"California", "Ontario"}
实现步骤:筛选→扁平化→聚合
我们可以把需求拆成三个独立的步骤,用函数式工具来实现:
1. 筛选目标州并扁平化数据
先用filter筛选出符合条件的州,再用map和生成器把嵌套结构展开成一维的条目(每条包含国家、日期、数值),避免多层嵌套循环:
# 用生成器+filter/map实现扁平化,节省内存 flattened_entries = ( {"country": country, **item} for country, states in original_data.items() # 过滤出目标州 for state in filter(lambda s: s in target_states, states.keys()) for city_data in states[state].values() # 用map处理每个日期条目(这里如果不需要额外转换,也可以直接用item) for item in map(lambda x: x, city_data) )
2. 用Reduce按国家+日期分组聚合
接下来用functools.reduce来做分组,核心逻辑是把每个条目按(country, date)作为键,聚合对应的数据(这里以求和为例,你可以按需修改聚合方式):
from functools import reduce def group_aggregator(accumulator, entry): # 用国家+日期作为唯一键 group_key = (entry["country"], entry["date"]) if group_key not in accumulator: accumulator[group_key] = 0 # 这里是求和聚合,你可以改成append收集所有值,或者其他操作 accumulator[group_key] += entry["value"] return accumulator # 执行分组聚合 grouped_result = reduce(group_aggregator, flattened_entries, {})
3. 转换为最终的嵌套字典格式(可选)
如果需要把结果转回类似原数据的嵌套结构(国家→日期→聚合值),可以再做一步转换:
final_dict = {} for (country, date), total in grouped_result.items(): if country not in final_dict: final_dict[country] = {} final_dict[country][date] = total # 输出结果 print(final_dict) # 输出: # {'USA': {'2024-01-01': 300, '2024-01-02': 400}, 'Canada': {'2024-01-01': 400, '2024-01-02': 450}}
为什么这种方式更好?
- 把筛选、扁平化、聚合拆成独立步骤,逻辑比多层嵌套循环更清晰,可读性更强;
- 用生成器替代列表,处理大数据时更节省内存;
- 聚合逻辑封装在
group_aggregator函数里,后续修改聚合规则(比如求平均值、收集所有值)只需要改这个函数即可。
内容的提问来源于stack exchange,提问作者halfcup
相关产品推荐
相关产品推荐

