如何在列表中查找重复值并合并它们

How to find duplicate values in a list and merge them

所以基本上例如你有一个像这样的列表:

l = ['a','b','a','b','c','c']

输出应该是:

[['a','a'],['b','b'],['c','c']]

所以基本上把重复的值放在一个列表中,

我试过了:

l = ['a','b','a','b','c','c']
it=iter(sorted(l))
next(it)
new_l=[]
for i in sorted(l):
   new_l.append([])
   if next(it,None)==i:
      new_l[-1].append(i)
   else:
      new_l.append([])

但是不管用,即使有用也不会高效

排序列表然后使用 itertools.groupby:

>>> from itertools import groupby
>>> l = ['a','b','a','b','c','c']
>>> [list(g) for _, g in groupby(sorted(l))]
[['a', 'a'], ['b', 'b'], ['c', 'c']]

编辑:这可能不是最快的方法,一般情况下排序的时间复杂度为 O(n log n),并非所有解决方案都需要(参见评论)

您可以使用 collections.Counter:

from collections import Counter
[[k] * c for k, c in Counter(l).items()]

这个returns:

[['a', 'a'], ['b', 'b'], ['c', 'c']]

%%timeit比较

  • 给定一个包含 100000 个值的样本数据集,此答案是最快的方法。

使用collections.Counter:

from collections import Counter

l = ['a','b','a','b','c','c']
c = Counter(l)

print([[x] * y for x, y in c.items()])
# [['a', 'a'], ['b', 'b'], ['c', 'c']]

这是 functional solution via itertools.groupby。由于需要排序,因此时间复杂度为 O(n log n).

from itertools import groupby
from operator import itemgetter

L = ['a','b','a','b','c','c']

res = list(map(list, map(itemgetter(1), groupby(sorted(L)))))

[['a', 'a'], ['b', 'b'], ['c', 'c']]

语法很繁琐,因为 Python 不提供本机函数组合。这由第 3 方库 toolz:

支持
from toolz import compose

foo = compose(list, itemgetter(1))
res = list(map(foo, groupby(sorted(L))))

可能不是最有效的,但这是可以理解的:

l = ['a','b','a','b','c','c']
dict = {}
for i in l:
    if dict[i]:
        dict[i] += 1
    else:
         dict[i] = 1

new = []
for key in list(dict.keys()):
    new.append([key] * dict[key])

另一种方法是使用 zip 方法。

l = ['a','b','a','b','c','c','b','c', 'a']
l = sorted(l)
grouped = [list(item) for item in list(zip(*[iter(l)] * l.count(l[0])))]

输出

[['a', 'a', 'a'], ['b', 'b', 'b'], ['c', 'c', 'c']]
l = ['a','b','a','b','c','c']

want = []
for i in set(l):
    want.append(list(filter(lambda x: x == i, l)))
print(want)    

我使用列表理解的解决方案是(l 是一个列表):

[l.count(x) * [x] for x in set(l)]
  • set(l) 将检索出现在 l 中的所有元素,没有 重复项
  • l.count(x) 将 return 特定元素 x 在给定列表中出现的次数 l
  • * 运算符 创建一个新列表,列表中的元素(在本例中为 [x])重复指定的次数(此处l.count(x)为次数)