将元组列表映射到字典,python

时间:2010-02-05 21:31:33

标签: python list dictionary tuples

我有一个从数据库中的表中提取的元组列表,它们看起来像( key foreignkey value )。 key和foreignkeys之间有多对一的关系,我想将它转换为由foreignkey索引的dict,其中包含所有值与该外键的总和,即{ foreignkey sumof( value }。我写了一些相当冗长的东西:

myDict = {}
for item in myTupleList:
    if item[1] in myDict:
        myDict [ item[1] ] += item[2]
    else:
        myDict [ item[1] ] = item[2]

但在看到this question's回答或these two之后,我必须更简洁地表达我想做的事情。如果这是重复,我错过了它,并将删除问题,如果你可以提供链接。

5 个答案:

答案 0 :(得分:8)

假设您的所有值均为int s,您可以使用defaultdict来简化此操作:

from collections import defaultdict

myDict = defaultdict(int)

for item in myTupleList:
    myDict[item[1]] += item[2]

defaultdict就像一个字典,除非你试图得到一个不在那里的密钥,它填充了callable返回的值 - 在这种情况下,int,当它返回0时没有参数调用。

更新:感谢@gnibbler提醒我,但是元组可以在for循环中解压缩:

from collections import defaultdict

myDict = defaultdict(int)

for _, key, val in myTupleList:
    myDict[key] += val

此处,3项元组将解压缩到变量_keyval中。 _是Python中常见的占位符名称,用于表示该值并不重要。使用此功能,我们可以避免毛茸茸的item[1]item[2]索引。如果myTupleList中的元组大小不同,我们就不能依赖于此,但我敢打赌它们是。

(我们还避免了某人查看代码并认为它​​已被破坏的情况,因为编写者认为数组是1索引的,这是我第一次阅读代码时的想法。直到我才解决这个问题。但是,在上面的循环中,很明显myTupleList是三个元素的元组,我们不需要第一个元素。)

答案 1 :(得分:5)

from collections import defaultdict

myDict = defaultdict(int)

for _, key, value in myTupleList:
    myDict[key] += value

答案 2 :(得分:4)

这是我的(脸颊)答案:

myDict = reduce(lambda d, t: (d.__setitem__(t[1], d.get(t[1], 0) + t[2]), d)[1], myTupleList, {})

这是丑陋和糟糕的,但这是它的工作原理。

减少的第一个参数(因为它不清楚)是lambda d, t: (d.__setitem__(t[1], d.get(t[1], 0) + t[2]), d)[1]。我稍后会讨论这个问题,但就目前而言,我只是称之为joe(对任何名叫乔的人都没有冒犯)。 reduce函数基本上是这样的:

 joe(joe(joe({}, myTupleList[0]), myTupleList[1]), myTupleList[2])

这是一个三元素列表。正如您所看到的,它基本上使用其第一个参数来将每个结果累积到最终答案中。在这种情况下,最终答案是您想要的字典。

现在为joe本身。以下joedef

def joe(myDict, tupleItem):
   myDict[tupleItem[1]] = myDict.get(tupleItem[1], 0) + tupleItem[2]
   return myDict

不幸的是,Python =中不允许使用任何形式的returnlambda,因此必须使用它。我通过直接调用= s dict函数来解决缺少__setitem__的问题。我通过创建一个返回值为__setitem__的元组和字典然后返回包含字典的元组元素来解决缺少返回问题。我将慢慢改变joe,以便你可以看到我是如何实现这一目标的。

首先,删除=

def joe(myDict, tupleItem):
   # Using __setitem__ to avoid using '='
   myDict.__setitem__(tupleItem[1], myDict.get(tupleItem[1], 0) + tupleItem[2])
   return myDict

接下来,将整个表达式求值为我们想要返回的值:

def joe(myDict, tupleItem):
   return (myDict.__setitem__(tupleItem[1], myDict.get(tupleItem[1], 0) + tupleItem[2]),
           myDict)[1]

我在Python编程中多次遇到reducedict这个用例。在我看来,dict可以使用成员函数reduceto(keyfunc, reduce_func, iterable, default_val=None)keyfunc将从iterable中获取当前值并返回密钥。 reduce_func将获取字典中的现有值和iterable中的值,并返回字典的新值。如果字典缺少密钥,default_val将被传递到reduce_func。返回值应该是字典本身,因此您可以执行以下操作:

myDict = dict().reduceto(lambda t: t[1], lambda o, t: o + t, myTupleList, 0)

答案 3 :(得分:0)

可能不完全可读但它应该有效:

fks = dict([ (v[1], True) for v in myTupleList ]).keys()
myDict = dict([ (fk, sum([ v[2] for v in myTupleList if v[1] == fk ])) for fk in fks ])

第一行找到所有唯一外键。第二行通过首先构建一个(fk,sum(此fk的所有值)) - 对并将其转换为字典的列表来构建字典。

答案 4 :(得分:0)

查看SQLAlchemy并查看是否可以完成所需的所有映射,也可以查看更多