我有两个字典列表(作为Django查询集返回).每个字典都有一个ID值.我想根据ID值将两者合并为一个词典列表.
例如:
list_a = [{'user__name': u'Joe', 'user__id': 1},
{'user__name': u'Bob', 'user__id': 3}]
list_b = [{'hours_worked': 25, 'user__id': 3},
{'hours_worked': 40, 'user__id': 1}]
Run Code Online (Sandbox Code Playgroud)
我想要一个函数来产生:
list_c = [{'user__name': u'Joe', 'user__id': 1, 'hours_worked': 40},
{'user__name': u'Bob', 'user__id': 3, 'hours_worked': 25}]
Run Code Online (Sandbox Code Playgroud)
其他要点:
list_a OUTER JOIN list_b USING user__id),我想要考虑该选项.user__id由于使用了数据库查询,每个列表中最多只有一个字典相同.非常感谢你的时间.
mgi*_*son 18
我itertools.groupby用来分组元素:
lst = sorted(itertools.chain(list_a,list_b), key=lambda x:x['user__id'])
list_c = []
for k,v in itertools.groupby(lst, key=lambda x:x['user__id']):
d = {}
for dct in v:
d.update(dct)
list_c.append(d)
#could also do:
#list_c.append( dict(itertools.chain.from_iterable(dct.items() for dct in v)) )
#although that might be a little harder to read.
Run Code Online (Sandbox Code Playgroud)
如果您厌恶lambda功能,可以随时使用operator.itemgetter('user__id').(它可能稍微有点效率)
为了揭开lambda/itemgetter的神秘面纱,请注意:
def foo(x):
return x['user__id']
Run Code Online (Sandbox Code Playgroud)
与以下任何一项相同*:
foo = operator.itemgetter('user__id')
foo = lambda x: x['user__id']
Run Code Online (Sandbox Code Playgroud)
*存在一些差异,但它们对此问题并不重要
from collections import defaultdict
from itertools import chain
list_a = [{'user__name': u'Joe', 'user__id': 1},
{'user__name': u'Bob', 'user__id': 3}]
list_b = [{'hours_worked': 25, 'user__id': 3},
{'hours_worked': 40, 'user__id': 1}]
collector = defaultdict(dict)
for collectible in chain(list_a, list_b):
collector[collectible['user__id']].update(collectible.iteritems())
list_c = list(collector.itervalues())
Run Code Online (Sandbox Code Playgroud)
如您所见,这只是使用另一个dict来合并现有的dicts.使用defaultdict的诀窍在于它消除了为新条目创建字典的苦差事.
无需对这些输入进行分组或排序.dict负责所有这些.
如果输入没有'user__id'键,真正的防弹解决方案可以捕获潜在的关键错误,或者使用默认值来收集没有这样的密钥的所有dicts.
| 归档时间: |
|
| 查看次数: |
3033 次 |
| 最近记录: |