python:重复数据删除并计算给定列表

时间:2017-03-22 16:08:21

标签: python list python-3.x duplicates

我使用以下代码来重复和计算给定列表:

def my_dedup_count(l):
    l.append(None)
    new_l = []
    current_x = l[0]
    current_count = 1
    for x in l[1:]:
        if x == current_x:
            current_count += 1
        else:
            new_l.append((current_x, current_count))
            current_x = x
            current_count = 1

    return new_l

使用我的测试代码:

my_test_list = ['a','a','b','b','b','c','c','d']
my_dedup_count(my_test_list)

结果是:

[('a', 2), ('b', 3), ('c', 2), ('d', 1)]

代码运行正常,输出正确。但是,我觉得我的代码非常冗长,我想知道有人会建议一种更优雅的方法来改进上面的代码吗?谢谢!

2 个答案:

答案 0 :(得分:3)

是的,不要重新发明轮子。改用标准库;你想在这里使用collections.Counter() class

from collections import Counter

def my_dedup_count(l):
    return Counter(l).items()

您可能只想返回计数器本身并使用它提供的所有功能(例如为您提供按计数排序的键计数列表)。

如果您预计只计算连续的次数(['a', 'b', 'a']会导致[('a', 1), ('b', 1), ('a', 1)],那么请使用itertools.groupby()

from itertools import groupby

def my_dedup_count(l):
    return [(k, sum(1 for _ in g)) for k, g in groupby(l)]

答案 1 :(得分:0)

我写了两个较短的方法来编写你所完成的内容。

此第一个选项忽略排序,列表中的所有类似值都将进行重复数据删除。

from collections import defaultdict

def my_dedup_count(test_list):
    foo = defaultdict(int)
    for el in test_list:
        foo[el] += 1

    return foo.items()

my_test_list = ['a','a','b','b','b','c','c','d', 'a', 'a', 'd']
>>> [('a', 4), ('c', 2), ('b', 3), ('d', 2)]

此第二个选项尊重顺序,仅重复删除连续的重复值。

def my_dedup_count(my_test_list):
output = []
succession = 1
for idx, el in enumerate(my_test_list):
    if idx+1 < len(my_test_list) and el == my_test_list[idx+1]:
        succession += 1
    else:
        output.append((el, succession))
        succession = 1

return output

my_test_list = ['a','a','b','b','b','c','c','d', 'a', 'a', 'd']
>>> [('a', 2), ('b', 3), ('c', 2), ('d', 1), ('a', 2), ('d', 1)]