代码之家  ›  专栏  ›  技术社区  ›  wheaties

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

  •  4
  • wheaties  · 技术社区  · 14 年前

    我有一个从数据库中的表中提取的元组列表,它看起来像( 钥匙 , 外星钥匙 , 价值 )键和foreignkey之间有一种多对一的关系,我想把它转换成foreignkey索引的dict,其中包含与foreignkey所有值的总和,即{ 外键 , 萨莫夫 价值 ) }。我写了一些相当冗长的东西:

    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 回复  |  直到 14 年前
        1
  •  8
  •   Community noseratio    7 年前

    假设你所有的价值观 int S,您可以使用 defaultdict 为了使这更容易:

    from collections import defaultdict
    
    myDict = defaultdict(int)
    
    for item in myTupleList:
        myDict[item[1]] += item[2]
    

    拖欠债务 就像一个字典,除非你试图得到一个不在那里的键,它会填充可调用返回的值——在本例中, 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] 索引。如果tuples在 myTupleList 不是所有的尺寸都一样,但我敢打赌。

    (我们还避免了有人看到代码并认为它已损坏的情况,因为编写者认为数组是1索引的,这是我第一次阅读代码时的想法。直到我读到这个问题,我才从中解脱出来。然而,在上面的循环中,很明显 鼓吹者 是由三个元素组成的元组,我们不需要第一个元素。)

        2
  •  5
  •   John La Rooy    14 年前
    from collections import defaultdict
    
    myDict = defaultdict(int)
    
    for _, key, value in myTupleList:
        myDict[key] += value
    
        3
  •  4
  •   Omnifarious    14 年前

    这是我(开玩笑)的回答:

    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])
    

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

    现在 本身。这里是 作为一个 def :

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

    不幸的是,没有任何形式的 = return 在python中允许 lambda 所以这必须得到解决。我克服了 = 通过调用 dict S __setitem__ 直接作用。我通过创建一个返回值为 _设置项__ 然后返回包含字典的tuple元素。我会慢慢改变 所以你可以看到我是怎么做到的。

    首先,移除 = :

    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]
    

    我遇到过这个用例 reduce 双关语 在我的python编程中很多次。在我看来, 双关语 无法使用成员函数 reduceto(keyfunc, reduce_func, iterable, default_val=None) . keyfunc 将从iterable中获取当前值并返回键。 reduce_func 将获取字典中的现有值和ITerable中的值,并返回字典的新值。 default_val 会成为过去 还原函数 如果字典缺少一个键。返回值应该是字典本身,这样您就可以执行以下操作:

    myDict = dict().reduceto(lambda t: t[1], lambda o, t: o + t, myTupleList, 0)
    
        4
  •  0
  •   Wim    14 年前

    可能不完全可读,但它应该工作:

    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的所有值))对列表并将其转换为字典来构建字典。

        5
  •  0
  •   mmmmmm    14 年前

    SQLAlchemy 看看这是否能完成你需要的所有映射,也许更多