与"What's the most concise way in Python to group and sum a list of objects by the same property"类似,我有一个脚本,我需要在其中总结对象列表的属性。但是,我的问题略有不同。
我有一类具有属性V,W,X,Y和Z的对象。我需要通过迭代并将属性W,X和Y与所有其他W,X和Y匹配来对属性Z求和属性相同。生成由W,X和Y索引的新求和值。
以下是对象的类:
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()]
我最初的想法是通过一系列嵌套的if语句来做到这一点,但这会大大减慢处理速度,而且我确信我的逻辑完全没有问题。
for xb in xbs:
if xb.W == xb.W:
if xb.X == xb.X:
if xb.Y == xb.Y:
sum(xb.Z)
对此有任何建议将不胜感激!
答案 0 :(得分:4)
您可以使用defaultdict执行此操作:
from collections import defaultdict
indexed_sums = defaultdict(int)
for o in xbs:
indexed_sums[(o.W, o.X, o.Y)] += o.Z
例如,如果您从(使用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)]
你最终得到:
print dict(indexed_sums)
# {(4, 3, 4): 8, (2, 3, 4): 15, (2, 3, 9): 3}
因此,你可以得到W,X,Y的总和为2,3,4为:
indexed_sums[(2, 3, 4)]
# 15
请注意defaultdict
在这里做的工作很少(它只是一个默认情况下从0开始的计数字典):主要的是你在字典中索引(o.W, o.X, o.Y)
元组。你可以在没有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
defaultdict
只是为你节省了两行。
答案 1 :(得分:0)
这是一个非常肮脏的单行内容:
{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')
)
)
}
我不建议这样做(调试很麻烦),但我认为这是一个有趣的解决方案