我在Python程序中有一个3元组列表,我正在查看文件(一次一个),并进行以下设置:
(feature,combination,durationOfTheCombination),
如果找到功能和组合的唯一组合,它将被添加到列表中。列表本身具有类似的设置,但durationOfTheCombination是共享(特征,组合)的唯一组合的所有持续时间的总和。因此,在决定是否应该将其添加到列表时,我只需要比较元组的前两部分,如果找到匹配,则将持续时间添加到相应的列表项中。
这是一个清晰的例子。如果输入是
(ABC,123,10);(ABC,123,10);(DEF,123,5);(ABC,123,30);(EFG,456,30)
输出将为(ABC,123,50);(DEF,123,5);(EFG,456,30)
。
有没有办法进行这种比较?
答案 0 :(得分:2)
您可以使用Counter
,
In [42]: from collections import Counter
In [43]: lst = [('ABC',123,10),('ABC',123,10),('DEF',123,5)]
In [44]: [(i[0],i[1],i[2]*j) for i,j in Counter(lst).items()]
Out[44]: [('DEF', 123, 5), ('ABC', 123, 20)]
根据OP的建议,如果它有不同的值,请使用groupby
In [26]: lst = [('ABC',123,10),('ABC',123,10),('ABC',123,25),('DEF',123,5)]
In [27]: [tuple(list(n)+[sum([i[2] for i in g])]) for n,g in groupby(sorted(lst,key = lambda x:x[:2]), key = lambda x:x[:2])]
Out[27]: [('ABC', 123, 45), ('DEF', 123, 5)]
答案 1 :(得分:1)
如果您不想使用Counter,则可以改用dict。
setOf3Tuples = dict()
def add3TupleToSet(a):
key = a[0:2]
if key in setOf3Tuples:
setOf3Tuples[a[0:2]] += a[2]
else:
setOf3Tuples[a[0:2]] = a[2]
def getRaw3Tuple():
for k in setOf3Tuples:
yield k + (setOf3Tuples[k],)
if __name__ == "__main__":
add3TupleToSet(("ABC",123,10))
add3TupleToSet(("ABC",123,10))
add3TupleToSet(("DEF",123,5))
print([i for i in getRaw3Tuple()])
答案 2 :(得分:1)
似乎dict比这里的列表更合适,前两个字段是关键。并且为了避免每次检查密钥是否已经在此处,您可以使用defaultdict。
from collections import defaultdict
d = defaultdict(int)
for t in your_list:
d[t[:2]] += t[-1]
答案 3 :(得分:0)
假设您的输入收集在下面的列表中,您可以使用pandas groupby快速完成此操作:
import pandas as pd
input = [('ABC',123,10),('ABC',123,10),('DEF',123,5),('ABC',123,30),('EFG',456,30)]
output = [tuple(x) for x in pd.DataFrame(input).groupby([0,1])[2].sum().reset_index().values]