给定这样的设置:
class Foo():
state = 'x'
amount = 1
a = Foo()
b = Foo()
c = Foo()
c.state = 'y'
foos = [a, b, c]
我想要一个dict,它的key=object.state
,values=sum(object.amounts of objects with that state)
。在这种情况下:
{'x': 2, 'y': 1}
我想自动做到这一点,所以我不需要提前知道不同的可能状态。
可以肯定的是,我可以用这样无聊的方式迭代:
my_dict = {}
for foo in foos:
try:
my_dict[foo.state] += foo.value
except (KeyError, TypeError):
my_dict[foo.state] = foo.value
但这有点冗长,我想知道是否有更好的方法来做到这一点,也许是通过dict理解或其他什么,但我迄今为止的努力都是徒劳的。
Counter
:怎么样
>>> from collections import Counter
>>>
>>> foos = [a,b,c]
>>>
>>> c = Counter()
>>> for x in foos:
c[x.state] += x.amount
>>> c
Counter({'x': 2, 'y': 1})
在这种情况下,字典理解并不是最优化的方法。相反,您可以使用collections.defaultdict()
,如下所示:
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>>
>>> for obj in foos:
... d[obj.state] += obj.amount
...
>>> d
defaultdict(<type 'int'>, {'y': 1, 'x': 2})
您可以使用defaultdict。
from collections import defaultdict
my_dict = defaultdict(lambda: 0)
for foo in foos:
my_dict[foo.type] += foo.value
您也可以使用setdefault。
my_dict = {}
for foo in foos:
my_dict.setdefault(foo.type, 0)
my_dict[foo.type] += foo.value