基于Python中的常见值合并/连接词典列表 [英] Merge/join lists of dictionaries based on a common value in Python
问题描述
例如:
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}]
我想要一个函数来产生:
list_c = [{'user__name':u'Joe','user__id':1,'hours_worked':40},
{'user__name':u'Bob','user__id' 'hours_worked':25}]
附加注意事项:
- 列表中的ID可能不是相同的顺序(如上面的示例)。
- 列表将可能具有相同数量的元素,但是如果不是将列表中的所有值保留下来,我想要考虑该选项_a(基本上
list_a OUTER JOIN list_b USING user__id
)。 - 我已经尝试在SQL中执行此操作,但是由于某些这些值是基于一些排除的聚合。
- 可以安全地假定,最多只能有一个字符相同的
user__id
每个列表由于使用数据库查询。
非常感谢您的时间。
我会使用 itertools.groupby
来分组元素:
lst = sorted(itertools.chain(list_a,list_b),key = lambda x:x ['user__id'])
list_c = []
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还可以:
#list_c.append(dict(itertools.chain.from_iterable(dct.items()for dct in v)))
#虽然可能有点难以阅读。
如果你厌恶 lambda
您可以随时使用 operator.itemgetter('user__id')
。 (这可能稍微更有效)
要对lambda / itemgetter进行一些神秘化,请注意:
def foo(x):
return x ['user__id']
与以下任一项相同:
foo = operator.itemgetter('user__id')
foo = lambda x:x ['user__id']
*有一些差异,但它们对于这个问题不重要。
I have two lists of dictionaries (returned as Django querysets). Each dictionary has an ID value. I'd like to merge the two into a single list of dictionaries, based on the ID value.
For example:
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}]
and I want a function to yield:
list_c = [{'user__name': u'Joe', 'user__id': 1, 'hours_worked': 40},
{'user__name': u'Bob', 'user__id': 3, 'hours_worked': 25}]
Additional points to note:
- The IDs in the lists may not be in the same order (as with the example above).
- The lists will probably have the same number of elements, but I want to account for the option if they're not but keeping all the values from list_a (essentially
list_a OUTER JOIN list_b USING user__id
). - I've tried doing this in SQL but it's not possible since some of the values are aggregates based on some exclusions.
- It's safe to assume there will only be at most one dictionary with the same
user__id
in each list due to the database queries used.
Many thanks for your time.
I'd use itertools.groupby
to group the elements:
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.
If you have an aversion to lambda
functions, you can always use operator.itemgetter('user__id')
instead. (it's probably slightly more efficient too)
To demystify lambda/itemgetter a little bit, Note that:
def foo(x):
return x['user__id']
is the same thing* as either of the following:
foo = operator.itemgetter('user__id')
foo = lambda x: x['user__id']
*There are a few differences, but they're not important for this problem
这篇关于基于Python中的常见值合并/连接词典列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!