Python选择性合并字典列表:优化嵌套代码的方法
用map/filter/lambda优化字典列表的合并(仅保留指定键)
嘿,刚接触Python的map、filter和lambda的话,用它们来简化这种“合并字典列表且只保留感兴趣键”的场景简直太合适了!我来帮你把原来嵌套较深的代码改得更清爽易读~
先明确需求
你有两个字典列表:
default_params_list:只关心其中的time_unit和city键foobar_list:只关心其中的type和start_date键
需要把两个列表中对应位置的字典合并,最终得到只包含这些指定键的新字典列表。
原来的嵌套写法(参考)
估计你之前可能会写类似这样的多层嵌套代码:
import copy merged = [] for default_dict, foobar_dict in zip(default_params_list, foobar_list): # 复制并过滤default字典 filtered_default = copy.deepcopy(default_dict) for key in list(filtered_default.keys()): if key not in ["time_unit", "city"]: del filtered_default[key] # 过滤并合并foobar字典的内容 filtered_foobar = {k: foobar_dict[k] for k in ["type", "start_date"]} filtered_default.update(filtered_foobar) merged.append(filtered_default)
这种写法嵌套多,读起来有点绕,现在用map、filter和lambda来简化它。
优化后的写法
default_params_list = [ { "abc": "some junk that we do not care", "time_unit": "week", "city": "atlanta" } ] foobar_list = [ { "type": "predict", "junk": "something we do not care", "start_date": "2018-09-01" } ] # 第一步:定义每个列表需要保留的键 default_keep_keys = {"time_unit", "city"} foobar_keep_keys = {"type", "start_date"} # 第二步:用map+lambda过滤每个字典,只保留需要的键 filtered_defaults = map(lambda d: {k: d[k] for k in default_keep_keys}, default_params_list) filtered_foobars = map(lambda d: {k: d[k] for k in foobar_keep_keys}, foobar_list) # 第三步:用map把对应位置的两个过滤后的字典合并 merged_list = list(map(lambda d1, d2: {**d1, **d2}, filtered_defaults, filtered_foobars)) print(merged_list) # 输出:[{'time_unit': 'week', 'city': 'atlanta', 'type': 'predict', 'start_date': '2018-09-01'}]
代码解释
- 过滤字典:用
map配合lambda,把每个原始字典转换成只包含指定键的新字典,这一步代替了原来的循环删除/复制逻辑,代码更线性。 - 合并字典:再次用
map,把两个过滤后的列表中对应位置的字典用字典解包{**d1, **d2}合并(Python 3.5及以上支持),最后转成列表(因为map返回的是迭代器)。
进阶:结合filter筛选特定条件的字典
如果还需要先筛选出符合特定条件的字典(比如只处理city为atlanta的条目),可以结合filter:
# 先筛选出city是atlanta的default字典,再过滤键 filtered_defaults = map(lambda d: {k: d[k] for k in default_keep_keys}, filter(lambda d: d.get("city") == "atlanta", default_params_list))
容错处理(可选)
如果担心原始字典中可能缺少指定键,可以用d.get(k)代替d[k],避免KeyError:
filtered_defaults = map(lambda d: {k: d.get(k, "") for k in default_keep_keys}, default_params_list) # 第二个参数是默认值,比如空字符串,也可以设为None
内容的提问来源于stack exchange,提问作者samxiao
相关产品推荐
相关产品推荐

