总结词典的价值

时间:2017-05-15 10:33:38

标签: python python-3.x dictionary

我有一本字典如下:

grocery={
    'James': {'Brocolli': 3, 'Carrot': 3, 'Cherry': 5},
    'Jill': {'Apples': 2, 'Carrot': 4, 'Tomatoes': 8},
    'Sunny': {'Apples': 5, 'Carrot': 2, 'Cherry': 2, 'Chicken': 3, 'Tomatoes': 6}
}
food={}
for a,b in grocery.items():
     for i,j in b.items():
          food[i]+=(b.get(i,0))

我正在尝试计算每种食物的总量,但它没有按预期工作。

例如:我想计算胡萝卜总数,苹果总数等等。

以上代码给出了以下错误:

File "dictionary1.py", line 6, in <module>
      food[i]+=(b.get(i,0))
   KeyError: 'Cherry

如何总结每个项目的总数?

3 个答案:

答案 0 :(得分:2)

您的food字典为空,一开始没有密钥;你不能只把一个值总结为尚未存在的东西。

取代+=,再次使用dict.get()获取当前值或默认

food[i] = food.get(i, 0) + b.get(i,0)

此处您不需要使用b.get(),因为已经在变量b中具有j的值:

food[i] = food.get(i, 0) + j

当您尝试使用默认值时,您还可以使用collections.defaultdict() object自动生成密钥:

from collections import defaultdict

food = defaultdict(int)  # insert int() == 0 when a key is not there yet

然后在内循环中使用food[i] += j

我强烈建议您为变量使用更好的名称。如果您遍历dict.values()而不是dict.items(),则只有在不需要密钥时才能查看这些值(例如外部for循环):

food = {}
for shopping in grocery.values():
    for name, quantity in shopping.items():
        food[name] = food.get(name, 0) + quantity

另一种选择是使用专用的计数和求和字典子类,称为collections.Counter()。本课程直接支持将您的杂货汇总到一行:

from collections import Counter

food = sum(map(Counter, grocery.values()), Counter())

map(Counter, ...)为每个输入词典创建Counter个对象,sum()将所有这些对象相加(额外的Counter()参数'primes'函数使用将Counter()作为起始值而不是整数0)。

后者的演示:

>>> from collections import Counter
>>> sum(map(Counter, grocery.values()), Counter())
Counter({'Tomatoes': 14, 'Carrot': 9, 'Cherry': 7, 'Apples': 7, 'Brocolli': 3, 'Chicken': 3})

Counter仍然是字典,只是一个具有额外功能的字典。通过将Counter传递给dict()

,您可以随时返回字典
>>> food = sum(map(Counter, grocery.values()), Counter())
>>> dict(food)
{'Brocolli': 3, 'Carrot': 9, 'Cherry': 7, 'Apples': 7, 'Tomatoes': 14, 'Chicken': 3}

答案 1 :(得分:2)

简单地做

from collections import defaultdict

food = defaultdict(int)&lt; - 每个不存在的键的默认值为0

..并且您的代码应该有效:)

PS。您收到错误是因为您正在尝试向未初始化的密钥添加值...不要假设不存在的密钥从0开始...

答案 2 :(得分:1)

你得到错误,因为在开始时,食物中不存在钥匙,即“苹果”,“西红柿”......。您可以使用try-except块更正此问题:

grocery={
    "Jill":{"Apples":2, "Tomatoes":8,"Carrot":4},
    "James":{"Carrot":3,"Brocolli":3,"Cherry":5},
    "Sunny":{"Chicken":3,"Apples":5,"Carrot":2,"Tomatoes":6,"Cherry":2}
}
food={}
for a,b in grocery.items():
    for i,j in b.items():
        try:
            food[i] += j
        except KeyError:
            food[i] = j

此外,你可以摆脱b.get(i,0)语句,因为你已经迭代了b并且只得到b中实际存在的值(j)。