我有一个包含属性qt
,cons
和consper
的对象列表,并且必须合并具有相同consper
值的所有对象。最好的方法是什么?该列表已按consper
排序。
实施例:
使用类house
的对象列表:
class house():
def __init__(self, qt, cons, consper):
self.qt = qt
self.cons = cons
self.consper = consper
转动此列表:
l = [
house(2, 20, 10),
house(3, 31, 10),
house(6, 70, 11),
house(2, 40, 20),
house(1, 25, 25)]
进入此列表:
l_new = [
house(5, 51, 10),
house(6, 70, 11),
house(2, 40, 20),
house(1, 25, 25)]
通过添加前两个对象(因为它们的属性包含等效)
答案 0 :(得分:2)
如果项目已按该属性排序,您可以使用itertools.groupby
获取组,sum
获取其他属性的总和。您还必须首先将组转换为list
,因为它们是迭代器。
>>> from itertools import groupby
>>> house.__repr__ = lambda h: "house(%r, %r, %r)" % (h.qt, h.cons, h.consper)
>>> [house(sum(h.qt for h in g), sum(h.cons for h in g), k)
... for k, g in ((k, list(g)) for k, g in groupby(l, key=lambda h: h.consper))]
[house(5, 51, 10), house(6, 70, 11), house(2, 40, 20), house(1, 25, 25)]
或使用字典:
>>> d = {}
>>> for h in l:
... qt, cons = d.get(h.consper, (0, 0))
... d[h.consper] = qt + h.qt, cons + h.cons
...
>>> [house(a, b, c) for a, (b, c) in d.items()]
[house(25, 1, 25), house(10, 5, 51), house(11, 6, 70), house(20, 2, 40)]
答案 1 :(得分:1)
您可以使用Failed to invoke gs
:
itertools.groupby
输出:
import itertools
class house():
def __init__(self, qt, cons, consper):
self.qt = qt
self.cons = cons
self.consper = consper
def __repr__(self):
return self.__class__.__name__+"({qt}, {cons}, {consper})".format(**self.__dict__)
l = [house(2, 20, 10),
house(3, 31, 10),
house(6, 70, 11),
house(2, 40, 20),
house(1, 25, 25)]
new_l = [(a, [(i.qt, i.cons) for i in list(b)]) for a, b in itertools.groupby(sorted(l, key=lambda x:x.consper), key=lambda x:x.consper)]
final_data = [house(*[sum(i) for i in zip(*b)]+[a]) for a, b in new_l]
答案 2 :(得分:1)
不使用itertools,你可以这样做:
class House():
def __init__(self, qt, cons, consper):
self.qt = qt
self.cons = cons
self.consper = consper
def __str__(self):
return "House(" + str(self.qt) + "," + str(self.cons) + "," + str(self.consper) + ")"
def __repr__(self):
return self.__str__()
def merge_dups(house_list):
res = []
house_map = {}
for h in house_list:
if h.consper in house_map:
other_house = house_map[h.consper]
merged_house = House(h.qt + other_house.qt,
h.cons + other_house.cons,
h.consper)
res.remove(other_house)
res.append(merged_house)
else:
house_map[h.consper] = h
res.append(h)
return res
print(merge_dups([
House(2, 20, 10),
House(3, 31, 10),
House(6, 70, 11),
House(2, 40, 20),
House(1, 25, 25)]))
输出
[House(5,51,10), House(6,70,11), House(2,40,20), House(1,25,25)]
答案 3 :(得分:0)
一个简单的解决方案是按如下方式使用词典:
l = [
house(2, 20, 10),
house(3, 31, 10),
house(6, 70, 11),
house(2, 40, 20),
house(1, 25, 25)]
dic= {}
for x in l :
temp = dic.get(x.consper,house(0,0,0))
x.qt += temp.qt
x.cons += temp.cons
dic[x.consper]=x
print('####################')
for x in dic.keys():
print(x)