我有一个包含类Element实例的python列表l
class Element:
def __init__(self, id, value):
self.id = id
self.value = value
l = [Element(1, 100), Element(1, 200), Element(2, 1), Element(3, 4), Element(3, 4)]现在我想对类Elements的所有value成员求和,如果它们的id等于获得这个列表:
l = [Element(1, 300), Element(2, 1), Element(3, 8)]要做到这一点,最具蟒蛇色彩的方式是什么?
发布于 2018-12-19 22:17:18
有(差不多?)没有itertools做不到的事情。看一看groupby
from itertools import groupby
from operator import attrgetter
class Element:
def __init__(self, id, value):
self.id = id
self.value = value
def __repr__(self): # kudos @mesejo
return "Element({}, {})".format(self.id, self.value)
l = [Element(1, 100), Element(1, 200), Element(2, 1), Element(3, 4), Element(3, 4)]
l.sort(key=attrgetter('id')) # if it is already sorted by 'id', comment-out
res = [Element(g, sum(sub.value for sub in k)) for g, k in groupby(l, key=attrgetter('id'))]这会导致:
print(res) # [Element(1, 300), Element(2, 1), Element(3, 8)]发布于 2018-12-19 22:18:27
一种方法是创建一个将ids映射到值和的defaultdict。然后我们可以利用这些结果并使用它们来构建一个新的Elements列表。为此,一种方法是使用starmap将该字典中的条目映射到Element的参数
from collections import defaultdict
from itertools import starmap
class Element:
def __init__(self, id, value):
self.id = id
self.value = value
def __repr__(self):
return "Element({}, {})".format(self.id, self.value)
l = [Element(1, 100), Element(1, 200), Element(2, 1), Element(3, 4), Element(3, 4)]
d = defaultdict(int)
for e in l:
d[e.id] += e.value
print(list(starmap(Element, d.items())))
# [Element(1, 300), Element(2, 1), Element(3, 8)]发布于 2018-12-19 22:36:58
您还可以使用set来获取惟一的ids,使用sum来合计值,从而获得所需的结果。例如:
class Element:
def __init__(self, id, value):
self.id = id
self.value = value
l = [Element(1, 100), Element(1, 200), Element(2, 1), Element(3, 4), Element(3, 4)]
ids = set(elem.id for elem in l)
totals = [Element(i, sum(elem.value for elem in l if elem.id == i)) for i in ids]
# [Element(1, 300), Element(2, 1), Element(3, 8)]https://stackoverflow.com/questions/53853038
复制相似问题