如何在Python中使用for循环查找数组中的重复元素?
我有一个重复元素的列表:
list_a=[1,2,3,5,6,7,5,2] tmp=[] for i in list_a: if tmp.__contains__(i): print i else: tmp.append(i)
我已经使用上面的代码来查找list_a
的重复元素。 我不想从列表中删除元素。
但是我想在这里使用for循环。 通常我们使用这样的C / C ++我猜:
for (int i=0;i<=list_a.length;i++) for (int j=i+1;j<=list_a.length;j++) if (list_a[i]==list_a[j]) print list_a[i]
我们如何在Python中这样使用?
for i in list_a: for j in list_a[1:]: ....
我试过上面的代码。 但它得到的解决scheme错了。 我不知道如何增加j
的价值。
仅供参考,在python 2.7+中,我们可以使用Counter
import collections x=[1, 2, 3, 5, 6, 7, 5, 2] >>> x [1, 2, 3, 5, 6, 7, 5, 2] >>> y=collections.Counter(x) >>> y Counter({2: 2, 5: 2, 1: 1, 3: 1, 6: 1, 7: 1})
唯一列表
>>> list(y) [1, 2, 3, 5, 6, 7]
find超过1次的项目
>>> [i for i in y if y[i]>1] [2, 5]
find的项目只有一次
>>> [i for i in y if y[i]==1] [1, 3, 6, 7]
使用in
运算符而不是直接调用__contains__
。
你几乎可以工作(但是是O(n ** 2)):
for i in xrange(len(list_a)): for j in xrange(i + 1, len(list_a)): if list_a[i] == list_a[j]: print "duplicate:", list_a[i]
但是使用一个集合(由于哈希表大致为O(n))要容易得多:
seen = set() for n in list_a: if n in seen: print "duplicate:", n else: seen.add(n)
或者一个字典,如果你想跟踪重复的位置(也O(n)):
import collections items = collections.defaultdict(list) for i, item in enumerate(list_a): items[item].append(i) for item, locs in items.iteritems(): if len(locs) > 1: print "duplicates of", item, "at", locs
甚至只是检测到重复的地方(也O(n)):
if len(set(list_a)) != len(list_a): print "duplicate"
你总是可以使用列表理解:
dups = [x for x in list_a if list_a.count(x) > 1]
在Python 2.3之前,使用dict():
>>> lst = [1, 2, 3, 5, 6, 7, 5, 2] >>> stats = {} >>> for x in lst : # count occurrences of each letter: ... stats[x] = stats.get(x, 0) + 1 >>> print stats {1: 1, 2: 2, 3: 1, 5: 2, 6: 1, 7: 1} # filter letters appearing more than once: >>> duplicates = [dup for (dup, i) in stats.items() if i > 1] >>> print duplicates
所以一个函数:
def getDuplicates(iterable): """ Take an iterable and return a generator yielding its duplicate items. Items must be hashable. eg : >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2]))) [2, 5] """ stats = {} for x in iterable : stats[x] = stats.get(x, 0) + 1 return (dup for (dup, i) in stats.items() if i > 1)
与Python 2.3来设置(),它甚至比以下内置:
def getDuplicates(iterable): """ Take an iterable and return a generator yielding its duplicate items. Items must be hashable. eg : >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2]))) [2, 5] """ try: # try using built-in set found = set() except NameError: # fallback on the sets module from sets import Set found = Set() for x in iterable: if x in found : # set is a collection that can't contain duplicate yield x found.add(x) # duplicate won't be added anyway
使用Python 2.7或更高版本,您可以使用collections
模块来提供与dict函数相同的function ,并且我们可以使其比解决scheme1更短(并且更快,可能是C)
import collections def getDuplicates(iterable): """ Take an iterable and return a generator yielding its duplicate items. Items must be hashable. eg : >>> sorted(list(getDuplicates([1, 2, 3, 5, 6, 7, 5, 2]))) [2, 5] """ return (dup for (dup, i) in collections.counter(iterable).items() if i > 1)
我会坚持解决scheme2。
def get_duplicates(arr): dup_arr = arr[:] for i in set(arr): dup_arr.remove(i) return list(set(dup_arr)) print get_duplicates([1,2,3,5,6,7,5,2]) [2, 5] print get_duplicates([1,2,1,3,4,5,4,4,6,7,8,2]) [1, 2, 4]
如果你正在寻找你的嵌套循环和Python之间的一对一映射,这是你想要的:
n = len(list_a) for i in range(n): for j in range(i+1, n): if list_a[i] == list_a[j]: print list_a[i]
上面的代码不是“Pythonic”。 我会做这样的事情:
seen = set() for i in list_a: if i in seen: print i else: seen.add(i)
另外,不要使用__contains__
,而是使用(如上)。
以下要求列表中的元素是可散列的(不仅仅是实现__eq__
)。 我发现使用defaultdict更为pythonic(你有免费的重复次数):
导入集合 l = [1,2,4,1,3,3] d = collections.defaultdict(int) for x in l: d [x] + = 1 如果v> 1,则打印[k代表k,v代表d.iteritems() #打印[1,3]
只使用itertools,并在Python 2.5上正常工作
from itertools import groupby list_a = sorted([1, 2, 3, 5, 6, 7, 5, 2]) result = dict([(r, len(list(grp))) for r, grp in groupby(list_a)])
结果:
{1: 1, 2: 2, 3: 1, 5: 2, 6: 1, 7: 1}
它看起来像你有一个列表( list_a
)可能包含重复,你宁愿保持原样,并build立一个基于list_a去重复列表tmp
。 在Python 2.7中,你可以用一行来完成:
tmp = list(set(list_a))
在这一点上比较tmp
和list_a
的长度应该说明list_a
中是否确实存在重复的项目。 如果你想进入循环进行额外的处理,这可能有助于简化事情。
你可以只是“逐行”翻译。
C ++
for (int i=0;i<=list_a.length;i++) for (int j=i+1;j<=list_a.length;j++) if (list_a[i]==list_a[j]) print list_a[i]
python
for i in range(0, len(list_a)): for j in range(i + 1, len(list_a)) if list_a[i] == list_a[j]: print list_a[i]
c ++ for循环:
for(int x = start; x < end; ++x)
相当于Python:
for x in range(start, end):
只是快速和肮脏,
list_a=[1,2,3,5,6,7,5,2] holding_list=[] for x in list_a: if x in holding_list: pass else: holding_list.append(x) print holding_list
输出[1,2,3,5,6,7]
使用numpy:
import numpy as np count,value = np.histogram(list_a,bins=np.hstack((np.unique(list_a),np.inf))) print 'duplicate value(s) in list_a: ' + ', '.join([str(v) for v in value[count>1]])
在Python3的情况下,如果你两个列表
def removedup(List1,List2): List1_copy = List1[:] for i in List1_copy: if i in List2: List1.remove(i) List1 = [4,5,6,7] List2 = [6,7,8,9] removedup(List1,List2) print (List1)
当然,我还没有做过testing,但是我想这个速度很难打败大pandas:
pd.DataFrame(list_a, columns=["x"]).groupby('x').size().to_dict()
Pythonic的一些实现(当然不是最多的),但是你的C代码的精神可能是:
for i, elem in enumerate(seq): if elem in seq[i+1:]: print elem
编辑:是的,如果有两个以上的重复,它会不止一次地打印这些元素,但这也是操作系统的C伪代码。