删除重复的值并将相应的列值相加

时间:2015-09-09 09:20:26

标签: python list duplicates

我有一个列表,我需要从中删除重复值并将相应的列值相加。清单是:

lst = [['20150815171000', '1', '2'],
       ['20150815171000', '2', '3'],
       ['20150815172000', '3', '4'],
       ['20150815172000', '4', '5'],
       ['20150815172000', '5', '6'],
       ['20150815173000', '6', '7']]

现在我需要遍历列表并获得如下输出:

lst2 = [['20150815171000', '3', '5'], 
        ['20150815172000', '12', '15'], 
        ['20150815173000', '6', '7']]

怎么可以这样做?我尝试编写如下所示的代码,但它只是比较连续的值而不是所有匹配的值。

    lst2 = []
    ws = wr = power = 0
    for i in range(len(lst)):
        if lst[i][0] == lst[i+1][0]:
            time = lst[i][0]
            ws = (float(lst[i][1])+float(lst[i+1][1]))
            wr = (float(lst[i][2])+float(lst[i+1][2]))      
        else:
           time = lst[i][0]
           ws = lst[i][1]
           wr = lst[i][2]
        lst2.append([time, ws, wr, power])

任何人都可以让我知道我该怎么做?

4 个答案:

答案 0 :(得分:5)

我会使用itertools.groupby,根据内部列表中的第一个元素进行分组。

所以我首先根据第一个元素对列表进行排序,然后根据它进行分组(如果列表已经在该元素上排序,那么你不需要再次排序,你可以直接分组)。

示例 -

new_lst = []
for k,g in itertools.groupby(sorted(lst,key=lambda x:x[0]) , lambda x:x[0]):
    l = list(g)
    new_lst.append([k,str(sum([int(x[1]) for x in l])), str(sum([int(x[2]) for x in l]))])

演示 -

>>> import itertools
>>>
>>> lst = [['20150815171000', '1', '2'],
...        ['20150815171000', '2', '3'],
...        ['20150815172000', '3', '4'],
...        ['20150815172000', '4', '5'],
...        ['20150815172000', '5', '6'],
...        ['20150815173000', '6', '7']]
>>>
>>> new_lst = []
>>> for k,g in itertools.groupby(sorted(lst,key=lambda x:x[0]) , lambda x:x[0]):
...     l = list(g)
...     new_lst.append([k,str(sum([int(x[1]) for x in l])), str(sum([int(x[2]) for x in l]))])
...
>>> new_lst
[['20150815171000', '3', '5'], ['20150815172000', '12', '15'], ['20150815173000', '6', '7']]

答案 1 :(得分:3)

您可以使用字典管理列表中的唯一条目。然后检查是否已经包含在dict键中的键。如果密钥已经在dict中,则添加到当前密钥,否则在dict中添加新条目。

试试这个:

#!/usr/bin/env python3

sums = dict()
for key, *values in lst:
    try:
        # add to an already present entry in the dict
        sums[key] = [int(x)+y for x, y in zip(values, sums[key])]
    except KeyError:
        # if the entry is not already present add it to the dict
        # and cast the values to int to make the adding easier
        sums[key] = map(int, values)

# build the output list from dictionary
# also cast back the values to strings
lst2 = sorted([[key]+list(map(str, values)) for key, values in sums.items()])

最后一行中的sorted可能是可选的。取决于您是否需要按dict键对输出列表进行排序。

请注意,这应该适用于密钥后的任何长度的值。

答案 2 :(得分:2)

使用字典清除 lambda sorted()。没有额外的库。

lst = [['20150815171000', '1', '2'],
       ['20150815171000', '2', '3'],
       ['20150815172000', '3', '4'],
       ['20150815172000', '4', '5'],
       ['20150815172000', '5', '6'],
       ['20150815173000', '6', '7']]

dct = dict()
for a, b, c in lst:
    if a not in dct: 
        dct[a] = [b, c] 
    else: 
        dct[a] = map(lambda x, y: str(int(x)+int(y)), dct[a], [b,c])
lst2 = sorted([[k,v[0],v[1]] for k,v in dct.items()])

print(lst2)

<强>输出:

[['20150815171000', '3', '5'], 
['20150815172000', '12', '15'], 
['20150815173000', '6', '7']]

答案 3 :(得分:1)

就像您对问题的评论一样,我也建议您使用字典寻求帮助。我不是一个优秀的程序员,并且有一些更好的方法,但这有效:

dct = dict()
for x, y, z in lst:
    if x not in dct:
        dct[x] = [y, z]
    else:
        dct[x] = [str(int(dct[x][0]) + int(y)), str(int(dct[x][1]) + int(z))]
lst2 = []
for k, v in dct.items():
    lst2.append([k, v[0], v[1]])

您基本上只是在列表上进行迭代,如果想要的数字(例如&#39; 2015081517100&#39;)尚未存在,则在字典中添加新项目,否则更新相应的值。最后,您只需在字典中的结果中创建另一个列表