基于Python中的公共值合并/连接字典列表

基于Python中的公共值合并/连接字典列表,python,django,Python,Django,我有两个字典列表(作为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'

我有两个字典列表(作为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}]
我想要一个函数来产生:

list_c = [{'user__name': u'Joe', 'user__id': 1, 'hours_worked': 40},
          {'user__name': u'Bob', 'user__id': 3, 'hours_worked': 25}]
需要注意的其他要点:

  • 列表中的ID顺序可能不同(与上面的示例相同)
  • 这些列表可能具有相同数量的元素,但如果它们不是而是保留列表a中的所有值(基本上是
    list\u a使用user\u id的外部联接列表b),我想说明这个选项
  • 我曾尝试在SQL中这样做,但这是不可能的,因为有些值是基于某些排除的聚合
  • 可以安全地假设,由于使用了数据库查询,每个列表中最多只有一个字典具有相同的
    user\u id

非常感谢您的时间。

我将使用
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.
如果您不喜欢
lambda
函数,您可以始终使用
operator.itemgetter('user\u id')
。(可能效率也稍微高一点)

要稍微揭开lambda/itemgetter的神秘面纱,请注意:

def foo(x):
    return x['user__id']
与以下任一项相同*:

foo = operator.itemgetter('user__id')
foo = lambda x: x['user__id']
*有一些不同之处,但它们对这个问题并不重要

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())
如您所见,这只是使用另一个dict来合并现有dict。defaultdict的诀窍在于它省去了为新条目创建dict的繁琐工作

无需对这些输入进行分组或排序。这一切都由法官来处理


如果输入没有“用户id”键,或者使用默认值收集没有该键的所有DICT,那么真正的防弹解决方案将捕获潜在的键错误。

您确定这些是元组吗?
{}
语法是用于字典的…这些不是元组,为什么不给我们看看你现在的代码呢?谢谢。我编辑了这个问题,并用字典替换了元组。这里可能是个不错的选择。一行式
[dict(y代表x中的x,y代表x中的y.items())代表k,g代表groupby(lis,key=lambda x:x['user\u id'])]
很好的解决方案,但值得注意的是,如果同一
user\u id
的多个
user\u id
行包含相同的值键,则这将破坏结果集中除最后一个值以外的所有值。对于这个问题可能没问题,但如果它是一个问题,可能会是一个棘手的问题。@sr2222--你是对的,它会这样做,但如果这是一个问题,那么这不是一个适定的问题(OP从未说过应该如何处理):)嗯,他提供的规范没有明确说明这种情况不会发生,但考虑到他所处理的数据类型,可能可以安全地假设没有重复数据。