大家有没有什么优雅的办法处理这样一段 Python 代码?

2019-10-29 10:00:47 +08:00
 dapengzhao
a_list = []
b_list = []
c_list = []
d_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 11, 'b': 22, 'c': 33}, {'a': 111, 'b': 222, 'c': 333}]

for i in d_dict:
    a_list.append(i['a'])
    b_list.append(i['b'])
    c_list.append(i['c'])

res_dict = {'a': a_list, 'b': b_list, 'c': c_list}
print(res_dict) # {'a': [1, 11, 111], 'b': [2, 22, 222], 'c': [3, 33, 333]}

需要处理的 d_dict 是 django 的一个 queryset,目标是生成一个新的字典,每个 k 对应一个列表,列表里是对应 queryset 某个 k 的所有值。 实际上还有好多字段,所以这段代码在项目里面看起来很臃肿,不知道大家有没有什么优雅的方法。 注意:只用一次 for 循环,

1671 次点击
所在节点    问与答
15 条回复
jakezh
2019-10-29 10:06:17 +08:00
用二维数组吧
Orenoid
2019-10-29 10:11:19 +08:00
from collections import defaultdict
result = defaultdict(list)
for i in d_dict:
result['a'].append(i['a'])
# b, c 同理
Orenoid
2019-10-29 10:14:07 +08:00
不过你的键值很多的话不应该用 dict.items() 来做二次循环吗,为什么一定要只用一次循环
Vegetable
2019-10-29 10:20:27 +08:00
首先你这个 abc_list 完全没必要定义,直接定义一个 res_dict={a:[],b:[].c:[]},就只剩下一行定义+一个循环了,而且可以像 3 楼说的直接
for i in d_dict:
for attr in (a,b,c):
res_dict[attrname].append(getattr(i,attrname))
这样两层循环去做
Vegetable
2019-10-29 10:21:01 +08:00
*for attrname in (a,b,c):
alienx717
2019-10-29 10:22:35 +08:00
妹得,我怎么感觉只是我以前写的代码哈哈哈
dapengzhao
2019-10-29 10:28:19 +08:00
@Orenoid 谢谢解决了,我定一次 for 循环是觉得有人会想用多次字典生成式来做,但是两次 for 循环完美解决
dapengzhao
2019-10-29 10:30:30 +08:00
```
d_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 11, 'b': 22, 'c': 33}, {'a': 111, 'b': 222, 'c': 333}]
d = defaultdict(list)
for i in d_dict:
for k, v in i.items():
d[k].append(v)
print(dict(d))
```
ipwx
2019-10-29 10:41:17 +08:00
In [1]: import pandas as pd

In [2]: df = pd.DataFrame(data=[{'a': 1, 'b': 2, 'c': 3}, {'a': 11, 'b': 22, 'c': 33}, {'a': 111, 'b': 222, 'c': 333}], columns=['a', 'b', 'c'])

In [3]: res_dict = {k: df[k].tolist() for k in df}

In [4]: res_dict
Out[4]: {'a': [1, 11, 111], 'b': [2, 22, 222], 'c': [3, 33, 333]}
ipwx
2019-10-29 10:42:27 +08:00
嘛,上面那个用 Pandas 的答案,一次 for 都不用。如果不是 web 应用而是数据处理,那么就是标准答案了。毕竟 pandas 就是用来干这种脏活的。。。
8Cangtou
2019-10-29 10:54:31 +08:00
{element_key: [n[element_key] for n in d_dict] for element_key in ["a", "b", "c"]}
8Cangtou
2019-10-29 10:54:54 +08:00
@8Cangtou
d_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 11, 'b': 22, 'c': 33}, {'a': 111, 'b': 222, 'c': 333}]
print {element_key: [n[element_key] for n in d_dict] for element_key in ["a", "b", "c"]}
xujunfu
2019-10-29 11:07:00 +08:00
In [13]: import pandas as pd

In [14]: d_dict = [{'a': 1, 'b': 2, 'c': 3}, {'a': 11, 'b': 22, 'c': 33}, {'a': 111, 'b': 222, 'c': 333}]

In [15]: res_dict = pd.DataFrame(d_dict).to_dict()
Kilerd
2019-10-29 11:07:25 +08:00
@ipwx #9 res_dict = {k: df[k].tolist() for k in df} 这个不是循环吗????
princelai
2019-10-29 13:50:34 +08:00
```
import pandas as pd

pd.DataFrame(d_dict).to_dict('list')
```


前提是你的 d_dict 里每一个 dict 是一样长

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/613914

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX