Contents
List元素合并到dict
David Wong提问
David Wong [email protected] 发件人当地时间: 发送时间 15:06 (GMT+08:00)。发送地当前时间:下午2:15。 ✆ 主题: [CPyUG] 上来求一个dict合并的优雅一点的方法
有这样一个list
1 qrs = [{'type': 'a', 'data': 'hello'},
2 {'type': 'b', 'data': 'hello1'},
3 {'type': 'b', 'data': 'hello2'},
4 {'type': 'b', 'data': 'hello3'},
5 {'type': 'a', 'data': 'hello4'},
6 {'type': 'a', 'data': 'hello5'},
7 {'type': 'b', 'data': 'hello6'},
8 {'type': 'b', 'data': 'hello7'}, ]
9
10 #想得到合并后的结果
11
12 result = [{'type': 'a', 'data': ['hello', 'hello4', 'hello5']},
13 {'type': 'b', 'data': ['hello1', 'hello2', 'hello3', 'hello6', 'hello7']}, ]
自己写了一段c样式代码实现了,但觉得很不优雅,很丑陋。 所以问问各位有什么更优雅更Pythonic的方法实现
WooParadog:itertools
WooParadog [email protected] 发件人当地时间: 发送时间 17:09 (GMT+08:00)。发送地当前时间:下午2:14。 ✆
1 if __name__ == '__main__':
2 qrs = [{'type': 'a', 'data': 'hello'},
3 {'type': 'b', 'data': 'hello1'},
4 {'type': 'b', 'data': 'hello2'},
5 {'type': 'b', 'data': 'hello3'},
6 {'type': 'a', 'data': 'hello4'},
7 {'type': 'a', 'data': 'hello5'},
8 {'type': 'b', 'data': 'hello6'},
9 {'type': 'b', 'data': 'hello7'},
10 ]
11
12 import itertools
13 import operator
14
15 li=[]
16 qrs.sort(key=operator.itemgetter('type'))
17 for k,g in itertools.groupby(qrs,key=operator.itemgetter('type')):
18 dic.append({'type':k,'data':[i['data'] for i in g]})
19 print li
Leo Jay:collections
Leo Jay [email protected] 发件人当地时间: 发送时间 11:30 (GMT+08:00)。发送地当前时间:下午2:12。 ✆
sunshine:setdefault()
sunshine [email protected] 发件人当地时间: 发送时间 12:43 (GMT+08:00)。发送地当前时间:下午2:10。 ✆
效能
雷钦 [email protected] 发件人当地时间: 发送时间 21:21 (GMT+08:00)。发送地当前时间:下午11:15。 ✆
我测了一下 defaultdict 最快:
groupby 0.11025595665 defaultdict 0.0313220024109 setdefault 0.050852060318
运行环境 python2.6.5 linux
运行代码:
1 #!/usr/bin/python
2
3 import sys
4 import random
5 import time
6 import itertools
7 import operator
8 import collections
9
10 def g(length, typerange):
11 return [{'type':random.randint(0,typerange),'data':'hello%s' % x } for x in xrange(length)]
12
13 def f1(qrs):
14 li=[]
15 qrs.sort(key=operator.itemgetter('type'))
16 for k,g in itertools.groupby(qrs,key=operator.itemgetter('type')):
17 li.append({'type':k,'data':[i['data'] for i in g]})
18 return li
19
20 def f2(qrs):
21 d = collections.defaultdict(list)
22 for q in qrs:
23 d[q['type']].append(q['data'])
24 result = [{'type': k, 'data': v} for k, v in d.items()]
25 return result
26
27 def f3(qrs):
28 new_list = {}
29 for elem in qrs:
30 new_list.setdefault(elem['type'], []).append(elem['data'])
31 result = [{'type': k, 'data': v} for k, v in new_list.items()]
32 return result
33
34 def t(f, a):
35 start = time.time()
36 f(a)
37 end = time.time()
38 return end - start
39
40 def main():
41 l = 100000
42 tr = 10
43 try:
44 l = int(sys.argv[1])
45 except:
46 pass
47
48 try:
49 tr = int(sys.argv[2])
50 except:
51 pass
52
53 print 'groupby %s' % t(f1,g(l,tr))
54 print 'defaultdict %s' % t(f2,g(l,tr))
55 print 'setdefault %s' % t(f3,g(l,tr))
56
57 if __name__ == '__main__':
58 main()
反馈
创建 by -- ZoomQuiet [2011-11-28 06:17:33]