如何在整数列表中找到重复项并创建重复项的另一个列表?
当前回答
我没有看到一个纯粹使用迭代器的解决方案,所以我们开始吧
这需要对列表进行排序,这可能是这里的缺点。
a = [1,2,3,2,1,5,6,5,5,5]
a.sort()
set(map(lambda x: x[0], filter(lambda x: x[0] == x[1], zip(a, a[1:]))))
{1, 2, 5}
你可以用这段代码轻松检查你的机器有多快,有一百万潜在的重复:
首先生成数据
import random
from itertools import chain
a = list(chain(*[[n] * random.randint(1, 2) for n in range(1000000)]))
并运行测试:
set(map(lambda x: x[0], filter(lambda x: x[0] == x[1], zip(a, a[1:]))))
不用说,这个解决方案只在列表已经排序的情况下才有效。
其他回答
我想在列表中找到重复项最有效的方法是:
from collections import Counter
def duplicates(values):
dups = Counter(values) - Counter(set(values))
return list(dups.keys())
print(duplicates([1,2,3,6,5,2]))
它对所有元素使用一次Counter,然后对所有唯一元素使用一次Counter。用第二个减去第一个,只剩下重复的部分。
使用Set函数 如:-
arr=[1,4,2,5,2,3,4,1,4,5,2,3]
arr2=list(set(arr))
print(arr2)
输出:- [1,2,3,4,5]
使用array删除副本
eg:-
arr=[1,4,2,5,2,3,4,1,4,5,2,3]
arr3=[]
for i in arr:
if(i not in arr3):
arr3.append(i)
print(arr3)
输出: [1,4,2,5,3]
使用Lambda函数
eg:-
rem_duplicate_func=lambda arr:set(arr)
print(rem_duplicate_func(arr))
输出: {1,2,3,4,5}
从字典中删除重复值
eg:-
dict1={
'car':["Ford","Toyota","Ford","Toyota"],
'brand':["Mustang","Ranz","Mustang","Ranz"] } dict2={} for key,value in dict1.items():
dict2[key]=set(value) print(dict2)
输出: {“车”:{“丰田”、“福特”},“品牌”:{“主攻”、“野马”}}
对称差异-删除重复元素
eg:-
set1={1,2,4,5}
set2={2,1,5,7}
rem_dup_ele=set1.symmetric_difference(set2)
print(rem_dup_ele)
输出: {4 7}
你可以使用iteration_utilities.duplicate:
>>> from iteration_utilities import duplicates
>>> list(duplicates([1,1,2,1,2,3,4,2]))
[1, 1, 2, 2]
或者如果你只想要一个副本,可以结合iteration_utilities.unique_everseen:
>>> from iteration_utilities import unique_everseen
>>> list(unique_everseen(duplicates([1,1,2,1,2,3,4,2])))
[1, 2]
它也可以处理不可哈希的元素(但是以性能为代价):
>>> list(duplicates([[1], [2], [1], [3], [1]]))
[[1], [1]]
>>> list(unique_everseen(duplicates([[1], [2], [1], [3], [1]])))
[[1]]
这是只有少数其他方法可以处理的问题。
基准
我做了一个快速的基准测试,其中包含了这里提到的大部分(但不是全部)方法。
第一个基准测试只包含了很小范围的列表长度,因为一些方法具有O(n**2)行为。
在图表中,y轴代表时间,所以值越低越好。它还绘制了log-log,以便更好地可视化广泛的值范围:
除去O(n**2)方法,我在一个列表中做了另一个多达50万个元素的基准测试:
正如您所看到的iteration_utilities。duplicate方法比任何其他方法都快,甚至连链接unique_everseen(duplicate(…))也比其他方法更快或同样快。
这里需要注意的另一件有趣的事情是,熊猫方法对于小列表非常慢,但可以轻松地竞争较长的列表。
然而,由于这些基准测试显示大多数方法的性能大致相同,因此使用哪一种并不重要(除了有O(n**2)运行时的3种方法)。
from iteration_utilities import duplicates, unique_everseen
from collections import Counter
import pandas as pd
import itertools
def georg_counter(it):
return [item for item, count in Counter(it).items() if count > 1]
def georg_set(it):
seen = set()
uniq = []
for x in it:
if x not in seen:
uniq.append(x)
seen.add(x)
def georg_set2(it):
seen = set()
return [x for x in it if x not in seen and not seen.add(x)]
def georg_set3(it):
seen = {}
dupes = []
for x in it:
if x not in seen:
seen[x] = 1
else:
if seen[x] == 1:
dupes.append(x)
seen[x] += 1
def RiteshKumar_count(l):
return set([x for x in l if l.count(x) > 1])
def moooeeeep(seq):
seen = set()
seen_add = seen.add
# adds all elements it doesn't know yet to seen and all other to seen_twice
seen_twice = set( x for x in seq if x in seen or seen_add(x) )
# turn the set into a list (as requested)
return list( seen_twice )
def F1Rumors_implementation(c):
a, b = itertools.tee(sorted(c))
next(b, None)
r = None
for k, g in zip(a, b):
if k != g: continue
if k != r:
yield k
r = k
def F1Rumors(c):
return list(F1Rumors_implementation(c))
def Edward(a):
d = {}
for elem in a:
if elem in d:
d[elem] += 1
else:
d[elem] = 1
return [x for x, y in d.items() if y > 1]
def wordsmith(a):
return pd.Series(a)[pd.Series(a).duplicated()].values
def NikhilPrabhu(li):
li = li.copy()
for x in set(li):
li.remove(x)
return list(set(li))
def firelynx(a):
vc = pd.Series(a).value_counts()
return vc[vc > 1].index.tolist()
def HenryDev(myList):
newList = set()
for i in myList:
if myList.count(i) >= 2:
newList.add(i)
return list(newList)
def yota(number_lst):
seen_set = set()
duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
return seen_set - duplicate_set
def IgorVishnevskiy(l):
s=set(l)
d=[]
for x in l:
if x in s:
s.remove(x)
else:
d.append(x)
return d
def it_duplicates(l):
return list(duplicates(l))
def it_unique_duplicates(l):
return list(unique_everseen(duplicates(l)))
基准1
from simple_benchmark import benchmark
import random
funcs = [
georg_counter, georg_set, georg_set2, georg_set3, RiteshKumar_count, moooeeeep,
F1Rumors, Edward, wordsmith, NikhilPrabhu, firelynx,
HenryDev, yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]
args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 12)}
b = benchmark(funcs, args, 'list size')
b.plot()
基准2
funcs = [
georg_counter, georg_set, georg_set2, georg_set3, moooeeeep,
F1Rumors, Edward, wordsmith, firelynx,
yota, IgorVishnevskiy, it_duplicates, it_unique_duplicates
]
args = {2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(2, 20)}
b = benchmark(funcs, args, 'list size')
b.plot()
免责声明
1这是我写的一个第三方库:iteration_utilities。
第三个接受答案的例子给出了一个错误的答案,并且没有试图给出重复的答案。下面是正确的版本:
number_lst = [1, 1, 2, 3, 5, ...]
seen_set = set()
duplicate_set = set(x for x in number_lst if x in seen_set or seen_set.add(x))
unique_set = seen_set - duplicate_set
list2 = [1, 2, 3, 4, 1, 2, 3]
lset = set()
[(lset.add(item), list2.append(item))
for item in list2 if item not in lset]
print list(lset)
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录