You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何更Pythonic地将数据类列表或嵌套数据类转换为列表字典?

嘿,这个需求确实有更简洁、更符合Pythonic风格的实现方式!我给你分享几种常用的方法,比嵌套循环+defaultdict要清爽得多:

方法1:字典推导式 + getattr

这是最直观的方式,直接通过字段名遍历生成结果字典:

import dataclasses
from typing import List

@dataclasses.dataclass
class A:
    a: str
    b: int

@dataclasses.dataclass
class B:
    l: List[A]

# 兼容两种输入情况:B实例或者直接是A的列表
da = B([A("a", 3), A("b", 4)])
items = da.l if isinstance(da, B) else da

# 获取A类的所有字段名
field_names = [field.name for field in dataclasses.fields(A)]

# 用字典推导式生成目标结果
result = {
    field: [getattr(item, field) for item in items]
    for field in field_names
}

print(result)  # 输出: {'a': ['a', 'b'], 'b': [3, 4]}

这种方法逻辑清晰,代码紧凑,完全不需要额外的defaultdict,直接通过字段名映射对应的属性列表。

方法2:dataclasses.asdict + zip解包

如果习惯用字典操作,可以先把每个A实例转成字典,再利用zip的解包特性聚合字段值:

# 承接上面的items和field_names
items_dicts = [dataclasses.asdict(item) for item in items]

# 用zip把所有字典的对应值聚合,再转成列表
result = {
    field: list(values)
    for field, values in zip(field_names, zip(*(d.values() for d in items_dicts)))
}

print(result)  # 输出: {'a': ['a', 'b'], 'b': [3, 4]}

这里的zip(*(d.values() for d in items_dicts))会把所有字典的第一个值、第二个值分别打包,刚好对应A类的字段顺序,再和字段名配对就得到了目标结果。

方法3:用Pandas快速转换(适合大数据场景)

如果你已经在使用Pandas处理数据,一行代码就能搞定:

import pandas as pd

result = pd.DataFrame([dataclasses.asdict(item) for item in items]).to_dict('list')
print(result)  # 输出: {'a': ['a', 'b'], 'b': [3, 4]}

这种方法适合需要对数据做进一步分析或处理的场景,不过会引入第三方库,按需选择即可。

对比你原来的实现,这些方法都更简洁直观,符合Python“用最少的代码做最多的事”的风格~

内容的提问来源于stack exchange,提问作者Claudiu Creanga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:03:12