##language:zh #pragma section-numbers off ##含有章节索引导航的 ZPyUG 文章通用模板 <> ## 默许导航,请保留 <> = List元素合并到dict = ##startInc == David Wong提问 == {{{ David Wong yydavid.wong@gmail.com 发件人当地时间: 发送时间 15:06 (GMT+08:00)。发送地当前时间:下午2:15。 ✆ 主题: [CPyUG] 上来求一个dict合并的优雅一点的方法 }}} 有这样一个list {{{ #!python qrs = [{'type': 'a', 'data': 'hello'}, {'type': 'b', 'data': 'hello1'}, {'type': 'b', 'data': 'hello2'}, {'type': 'b', 'data': 'hello3'}, {'type': 'a', 'data': 'hello4'}, {'type': 'a', 'data': 'hello5'}, {'type': 'b', 'data': 'hello6'}, {'type': 'b', 'data': 'hello7'}, ] #想得到合并后的结果 result = [{'type': 'a', 'data': ['hello', 'hello4', 'hello5']}, {'type': 'b', 'data': ['hello1', 'hello2', 'hello3', 'hello6', 'hello7']}, ] }}} 自己写了一段c样式代码实现了,但觉得很不优雅,很丑陋。 所以问问各位有什么更优雅更Pythonic的方法实现 === WooParadog:itertools === {{{ WooParadog guohaochuan@gmail.com 发件人当地时间: 发送时间 17:09 (GMT+08:00)。发送地当前时间:下午2:14。 ✆ }}} {{{ #!python if __name__ == '__main__': qrs = [{'type': 'a', 'data': 'hello'}, {'type': 'b', 'data': 'hello1'}, {'type': 'b', 'data': 'hello2'}, {'type': 'b', 'data': 'hello3'}, {'type': 'a', 'data': 'hello4'}, {'type': 'a', 'data': 'hello5'}, {'type': 'b', 'data': 'hello6'}, {'type': 'b', 'data': 'hello7'}, ] import itertools import operator li=[] qrs.sort(key=operator.itemgetter('type')) for k,g in itertools.groupby(qrs,key=operator.itemgetter('type')): dic.append({'type':k,'data':[i['data'] for i in g]}) print li }}} === Leo Jay:collections === {{{ Leo Jay python.leojay@gmail.com 发件人当地时间: 发送时间 11:30 (GMT+08:00)。发送地当前时间:下午2:12。 ✆ }}} {{{ #!python from collections import defaultdict d = defaultdict(list) [d[q['type']].append(q['data']) for q in qrs] result = [{'type': k, 'data': v} for k, v in d.items()] print result }}} === sunshine:setdefault() === {{{ sunshine zy.netsec@gmail.com 发件人当地时间: 发送时间 12:43 (GMT+08:00)。发送地当前时间:下午2:10。 ✆ }}} {{{ #!python new_list = {} for elem in qrs: new_list.setdefault(elem['type'], []).append(elem['data']) print new_list }}} == 效能 == {{{ 雷钦 leiqin2010@gmail.com 发件人当地时间: 发送时间 21:21 (GMT+08:00)。发送地当前时间:下午11:15。 ✆ }}} 我测了一下 defaultdict 最快: {{{ groupby 0.11025595665 defaultdict 0.0313220024109 setdefault 0.050852060318 }}} 运行环境 python2.6.5 linux 运行代码: {{{ #!python #!/usr/bin/python import sys import random import time import itertools import operator import collections def g(length, typerange): return [{'type':random.randint(0,typerange),'data':'hello%s' % x } for x in xrange(length)] def f1(qrs): li=[] qrs.sort(key=operator.itemgetter('type')) for k,g in itertools.groupby(qrs,key=operator.itemgetter('type')): li.append({'type':k,'data':[i['data'] for i in g]}) return li def f2(qrs): d = collections.defaultdict(list) for q in qrs: d[q['type']].append(q['data']) result = [{'type': k, 'data': v} for k, v in d.items()] return result def f3(qrs): new_list = {} for elem in qrs: new_list.setdefault(elem['type'], []).append(elem['data']) result = [{'type': k, 'data': v} for k, v in new_list.items()] return result def t(f, a): start = time.time() f(a) end = time.time() return end - start def main(): l = 100000 tr = 10 try: l = int(sys.argv[1]) except: pass try: tr = int(sys.argv[2]) except: pass print 'groupby %s' % t(f1,g(l,tr)) print 'defaultdict %s' % t(f2,g(l,tr)) print 'setdefault %s' % t(f3,g(l,tr)) if __name__ == '__main__': main() }}} ##endInc ---- '''反馈''' 创建 by -- ZoomQuiet [<>]