如何用Pythonic方式将值为列表的字典展开为字典列表?
如何Pythonic地展开值为列表的字典
需求说明
输入一个值均为列表的字典:
{'a': [1, 2, 3], 'b': [4, 5, 6]}
需要将其展开为字典列表,每个子字典对应原字典各列表的同位置元素:
[{'a': 1, 'b': 4}, {'a': 2, 'b': 5}, {'a': 3, 'b': 6}]
原有实现
你当前的实现逻辑可行,但可以通过Python内置特性简化:
def flatten_dict(d: dict) -> list[dict]: """ get [{'a': 1, 'b': 4}, {'a': 2, 'b': 5}] from {'a': [1, 2], 'b': [4, 5]} :param d: dict object :return: list of dicts """ values = list(d.values()) val_zip = list(zip(*values)) keys = [list(d.keys())] * len(values[0]) bonded_vals = list(zip(keys, val_zip)) return list(map(lambda p: dict(zip(p[0], p[1])), bonded_vals))
优化方案(Pythonic写法)
利用列表推导式和zip()函数可以大幅简化代码,同时保持可读性:
等长列表场景
def flatten_dict(d: dict) -> list[dict]: """将值为等长列表的字典展开为字典列表""" keys = list(d.keys()) return [dict(zip(keys, item)) for item in zip(*d.values())]
- 先一次性提取字典的所有键
keys,避免重复生成 zip(*d.values())会将各列表的同位置元素打包成元组(如(1,4), (2,5), (3,6))- 列表推导式遍历每个打包后的元组,用
dict(zip(keys, item))直接生成对应字典
不等长列表场景(可选)
如果需要处理列表长度不一致的情况,可以使用itertools.zip_longest填充默认值:
from itertools import zip_longest def flatten_dict(d: dict, fillvalue=None) -> list[dict]: """展开值为列表的字典,支持不等长列表,缺失值用fillvalue填充""" keys = list(d.keys()) return [dict(zip(keys, item)) for item in zip_longest(*d.values(), fillvalue=fillvalue)]
示例输入{'a': [1,2], 'b': [3,4,5]}会输出:
[{'a': 1, 'b': 3}, {'a': 2, 'b': 4}, {'a': None, 'b': 5}]
内容的提问来源于stack exchange,提问作者inquilabee
相关产品推荐
相关产品推荐

