生成python字典只存储来自iterable的最后一个值

时间:2014-03-08 06:57:19

标签: python django dictionary

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

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

2 个答案:

答案 0 :(得分:3)

你可以明确地总结:

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

正如您已经注意到的,如果您使用普通字典理解,后面的项目会覆盖之前的项目而不是求和。

答案 1 :(得分:1)

您不能将具有多个值的字典理解用于一个键。它会不断覆盖。您必须使用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)