我有一本字典如下:
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
如何总结每个项目的总数?
答案 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)。