我有一个从数据库中的表中提取的元组列表,它们看起来像( 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之后,我必须更简洁地表达我想做的事情。如果这是重复,我错过了它,并将删除问题,如果你可以提供链接。
答案 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项元组将解压缩到变量_
,key
和val
中。 _
是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
本身。以下joe
为def
:
def joe(myDict, tupleItem):
myDict[tupleItem[1]] = myDict.get(tupleItem[1], 0) + tupleItem[2]
return myDict
不幸的是,Python =
中不允许使用任何形式的return
或lambda
,因此必须使用它。我通过直接调用=
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编程中多次遇到reduce
和dict
这个用例。在我看来,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并查看是否可以完成所需的所有映射,也可以查看更多