【问题标题】:Generating python dictionary only stores last value from iterable生成python字典只存储可迭代的最后一个值
【发布时间】:2014-03-08 06:57:18
【问题描述】:

这是从数据库返回的对象列表:

>>> credit_transactions

[<Transaction: some detail>, <Transaction: more detail>, <Transaction: hello>, <Transaction: yay dummy data>]

以下是我用来生成字典的代码。 这就是我想要做的,如果tr.category 不止一次可用,那么tr.amount 应该被添加到最后一个值。 我现在得到的只是tr.category 的最后一个值。

credit = { tr.category:tr.amount for tr in credit_transactions}

对于credit_transactions的后面的值,上面提到的代码只为最后一个值生成了字典键值对。如果键重复,我想要值的总和。

>>> for tr in credit_transactions:
...  tr.category
... 
<Category: Bonus>
<Category: Lottery>
<Category: Lottery>
<Category: Bonus>
<Category: Salary>
<Category: Bonus>
>>> 

【问题讨论】:

    标签: python django dictionary


    【解决方案1】:

    你可以明确地求和:

    sums = {}
    for tr in credit_transactions:
        try:
            sums[tr.category] += tr.amount  # not first in this category
        except KeyError:
            sums[tr.category] = tr.amount  # first in this category
    

    或者使用defaultdict,它会自动将缺失的键初始化为零:

    from collections import defaultdict
    sums = defaultdict(float)
    for tr in credit_transactions:
        sums[tr.category] += tr.amount
    

    正如您已经注意到的,如果您使用普通的 dict-comprehension,后面的项目会覆盖前面的项目,而不是求和。

    【讨论】:

    • 正确!正是我需要的。谢谢:)
    【解决方案2】:

    您不能对一个键使用多个值的字典推导。它将不断覆盖。您必须使用defaultdict(或dict.setdefault

    defaultdict 默认创建所有值列表。 (documentation):

    from collections import defaultdict
    
    credit = defaultdict(list)
    for tr in credit_transactions:
        credit[tr.category].append(tr.amount)
    

    dict.setdefault 如果为空,则设置为空列表。 (documentation)

    credit = {}
    for tr in credit_transactions:
        credit.setdefault(tr.category, []).append(tr.amount)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-31
      • 1970-01-01
      • 2021-07-29
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多