我使用以下代码来重复和计算给定列表:
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)]
代码运行正常,输出正确。但是,我觉得我的代码非常冗长,我想知道有人会建议一种更优雅的方法来改进上面的代码吗?谢谢!
答案 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)]