[英]Summing Attribute in a list of Python Objects
Similar to "What's the most concise way in Python to group and sum a list of objects by the same property" , I have a script in which I need to sum the attributes of list of objects. 类似于“ Python中用同一属性对对象列表进行分组和汇总的最简洁方法是什么” ,我有一个脚本,需要在其中添加对象列表的属性。 However, my issue differs slightly. 但是,我的问题略有不同。
I have a class of objects with attributes V, W, X, Y, and Z. I need to sum attribute Z by iterating through and matching the attributes W, X, and Y with all other W, X, and Y attributes that are the same. 我有一类具有属性V,W,X,Y和Z的对象。我需要通过遍历属性W,X和Y并将其与所有其他W,X和Y属性进行匹配来对属性Z求和相同。 Producing a new summed value that is indexed by W, X, and Y. 产生一个由W,X和Y索引的新求和值。
Here is the class for the objects: 这是对象的类:
class xb(object):
def __init__(self, V, W, X, Y, Z):
self.V = V
self.W = W
self.X = X
self.Y = Y
self.Z = Z
xbs = [xb()]
My initial thought was to do this through a series of nested if statements but this slows processing considerably and I'm sure my logic is all out of whack. 我最初的想法是通过一系列嵌套的if语句来执行此操作,但是这会大大减慢处理速度,而且我确信我的逻辑是不明智的。
for xb in xbs:
if xb.W == xb.W:
if xb.X == xb.X:
if xb.Y == xb.Y:
sum(xb.Z)
Any suggestions on this would be greatly appreciated! 任何建议对此将不胜感激!
You can do this using a defaultdict: 您可以使用defaultdict执行此操作:
from collections import defaultdict
indexed_sums = defaultdict(int)
for o in xbs:
indexed_sums[(o.W, o.X, o.Y)] += o.Z
For instance, if you start with (using your class definition of xb
): 例如,如果您开始使用(使用xb
的类定义):
xbs = [xb(1, 2, 3, 4, 5),
xb(1, 2, 3, 4, 5),
xb(1, 2, 3, 4, 5),
xb(1, 4, 3, 4, 5),
xb(1, 4, 3, 4, 3),
xb(1, 2, 3, 9, 3)]
You end up with: 您最终得到:
print dict(indexed_sums)
# {(4, 3, 4): 8, (2, 3, 4): 15, (2, 3, 9): 3}
Thus, you could get the sum for W, X, Y being 2, 3, 4 as: 因此,您可以获得W,X,Y为2、3、4的总和为:
indexed_sums[(2, 3, 4)]
# 15
Note that the defaultdict
is doing very little work here (it's just a dictionary of counts that starts at 0 by default): the main thing is that you are indexing the (oW, oX, oY)
tuples in a dictionary. 请注意, defaultdict
在这里所做的工作很少(这只是一个默认为0的计数字典):主要是要在字典中索引(oW, oX, oY)
元组。 You could have done the same thing without defaultdict
as: 如果没有defaultdict
,您可能会做同样的事情:
indexed_sums = {}
for o in xbs:
if (o.W, o.X, o.Y) not in indexed_sums:
indexed_sums[(o.W, o.X, o.Y)] = 0
indexed_sums[(o.W, o.X, o.Y)] += o.Z
The defaultdict
is just saving you two lines. defaultdict
只为您节省了两行。
Here's a very dirty hack of a one-liner: 这是一个单线的非常肮脏的技巧:
{key:sum(g.Z for g in group)
for key, group in
itertools.groupby(
sorted(L, key=lambda p:tuple((operator.attrgetter(a)(p) for a in 'VWXYZ'))),
key=lambda p:tuple(
(operator.attrgetter(a)(p) for a in 'VWXYZ')
)
)
}
I don't recommend doing this at all (it's a pain to debug), but I think it's an interesting solution nonetheless 我完全不建议这样做(调试起来很痛苦),但是我仍然认为这是一个有趣的解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.