如何在整数列表中找到重复项并创建重复项的另一个列表?
当前回答
要删除重复项,请使用集合(a)。要打印副本,可以这样做:
a = [1,2,3,2,1,5,6,5,5,5]
import collections
print([item for item, count in collections.Counter(a).items() if count > 1])
## [1, 2, 5]
请注意Counter并不是特别有效(计时),可能会在这里过度使用。Set会表现得更好。这段代码以源顺序计算一个唯一元素的列表:
seen = set()
uniq = []
for x in a:
if x not in seen:
uniq.append(x)
seen.add(x)
或者,更简洁地说:
seen = set()
uniq = [x for x in a if x not in seen and not seen.add(x)]
我不推荐后一种风格,因为它不清楚not seen.add(x)在做什么(set add()方法总是返回None,因此需要not)。
计算没有库的重复元素列表:
seen = set()
dupes = []
for x in a:
if x in seen:
dupes.append(x)
else:
seen.add(x)
或者,更简洁地说:
seen = set()
dupes = [x for x in a if x in seen or seen.add(x)]
如果列表元素不可哈希,则不能使用set /dicts,必须使用二次时间解决方案(逐个比较)。例如:
a = [[1], [2], [3], [1], [5], [3]]
no_dupes = [x for n, x in enumerate(a) if x not in a[:n]]
print no_dupes # [[1], [2], [3], [5]]
dupes = [x for n, x in enumerate(a) if x in a[:n]]
print dupes # [[1], [3]]
其他回答
使用toolz时:
from toolz import frequencies, valfilter
a = [1,2,2,3,4,5,4]
>>> list(valfilter(lambda count: count > 1, frequencies(a)).keys())
[2,4]
方法1:
list(set([val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]))
解释: [val for idx, val in enumerate(input_list) if val in input_list[idx+1:]]是一个列表推导式,它返回一个元素,如果该元素从当前位置存在,则在列表中返回下标。
例子: input_list =[3 42 42岁,31日,31日,31日,31日,5日,6日6日6日6日6日,7日,42)
从索引为0的列表第一个元素42开始,它检查元素42是否存在于input_list[1:]中(即从索引1到列表末尾)。 因为42存在于input_list[1:]中,它将返回42。
然后它转到下一个索引为1的元素31,并检查元素31是否存在于input_list[2:](即从索引2到列表末尾), 因为31存在于input_list[2:]中,它将返回31。
类似地,它遍历列表中的所有元素,只将重复/重复的元素返回到列表中。
然后,因为列表中有重复项,我们需要从每个重复项中选择一个,即从重复项中删除重复项,为此,我们调用python内置的名为set()的函数,它会删除重复项,
然后我们就得到了一个集合,而不是一个列表,因此为了将集合转换为列表,我们使用类型转换,list(),它将元素集转换为列表。
方法2:
def dupes(ilist):
temp_list = [] # initially, empty temporary list
dupe_list = [] # initially, empty duplicate list
for each in ilist:
if each in temp_list: # Found a Duplicate element
if not each in dupe_list: # Avoid duplicate elements in dupe_list
dupe_list.append(each) # Add duplicate element to dupe_list
else:
temp_list.append(each) # Add a new (non-duplicate) to temp_list
return dupe_list
解释: 首先,我们创建两个空列表。 然后继续遍历列表中的所有元素,以查看temp_list(最初为空)中是否存在该元素。如果它不在temp_list中,则使用append方法将它添加到temp_list中。
如果它已经存在于temp_list中,这意味着列表中的当前元素是重复的,因此我们需要使用append方法将它添加到dupe_list中。
我是很晚才开始讨论这个问题的。尽管如此,我还是想用一句话来解决这个问题。因为这就是Python的魅力所在。 如果我们只是想把副本放到一个单独的列表(或任何集合)中,我建议这样做。假设我们有一个重复的列表我们称之为目标
target=[1,2,3,4,4,4,3,5,6,8,4,3]
现在如果我们想要得到副本,我们可以使用下面的一行代码:
duplicates=dict(set((x,target.count(x)) for x in filter(lambda rec : target.count(rec)>1,target)))
这段代码将把复制的记录作为键,并将其作为值放入字典'duplicate '中。“复制”字典将如下所示:
{3: 3, 4: 4} #it saying 3 is repeated 3 times and 4 is 4 times
如果你只是想在一个列表中单独列出所有重复的记录,它的代码也更短:
duplicates=filter(lambda rec : target.count(rec)>1,target)
输出将是:
[3, 4, 4, 4, 3, 4, 3]
这在python 2.7中完美地工作。X +版本
假设我们有这个元素列表:
a = [1, 2, 3, 2, 1, 5, 6, 5, 5, 5]
我们可以只使用集合来找到唯一的元素:
unique = set()
for num in a:
if num not in unique:
unique.add(num)
else:
unique = unique - set([num])
最后:
>>> unique
{3, 6}
如果你想要得到副本,你可以简单地做:
>>> duplicates = set(a) - unique
>>> duplicates
{1, 2, 5}
注:
集合中的元素查找是O(1) 从集合中移除的元素是O(1)
一个非常简单的解决方案,但是复杂度是O(n*n)。
>>> xs = [1,2,3,4,4,5,5,6,1]
>>> set([x for x in xs if xs.count(x) > 1])
set([1, 4, 5])