web-dev-qa-db-ja.com

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:]:
    ....

上記のコードを試しました。しかし、解決策が間違っています。 jの値を増やす方法がわかりません。

22
Beginner

参考のために、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]

アイテムが複数回見つかった

>>> [i for i in y if y[i]>1]
[2, 5]

一度だけ見つかったアイテム

>>> [i for i in y if y[i]==1]
[1, 3, 6, 7]
56
YOU

__contains__を直接呼び出す代わりに、in演算子を使用します。

あなたがほとんど動作しているもの(しかし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"
24
Roger Pate

常にリスト内包表記を使用できます:

dups = [x for x in list_a if list_a.count(x) > 1]
17
Evan Fosmark

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.

       e.g :

       >>> 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がset()に付属し、それは以下よりもビルトインです:

def getDuplicates(iterable):
    """
       Take an iterable and return a generator yielding its duplicate items.
       Items must be hashable.

       e.g :

       >>> 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のものとまったく同じ機能を提供しますがあり、それを短くすることができます(そして解決策1よりも高速で、おそらくボンネットの下のCです):

import collections

def getDuplicates(iterable):
    """
       Take an iterable and return a generator yielding its duplicate items.
       Items must be hashable.

       e.g :

       >>> 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)

私は解決策2に固執します。

8
e-satis

この関数を使用して、重複を見つけることができます。

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]

6
HOT

ネストされたループとPythonの間の1対1のマッピングを探している場合、これが必要です。

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__を使用せず、代わりにinを使用してください(上記を参照)。

3
Alok Singhal

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}
2
Zoran Pavlovic

以下では、リストの要素がハッシュ可能でなければなりません(__eq__)。 defaultdictを使用するほうがPythonicであることがわかります(繰り返し回数は無料です):

インポートコレクション
 l = [1、2、4、1、3、3] 
 d = collections.defaultdict(int)
 x in l: 
 d [x] + = 1 
 print [k for k、v in d.iteritems()if v> 1] 
#prints [1、3] 
2
LeMiz

重複を含む可能性のあるリスト(_list_a_)があり、それをそのままにしておき、list_aに基づいて重複を排除したリストtmpを作成しているようです。 Python 2.7では、1行でこれを実現できます。

tmp = list(set(list_a))

この時点でtmpと_list_a_の長さを比較すると、_list_a_に実際に重複する項目があるかどうかが明確になります。これは、追加の処理のためにループに入る場合に物事を簡素化するのに役立ちます。

1
Ahmer Kureishi

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]])
0
Juh_

確かに、私はテストを行っていませんが、スピードでpandasを打つのは難しいでしょう。

 pd.DataFrame(list_a, columns=["x"]).groupby('x').size().to_dict()
0
Make42

早くて汚い、

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]

0
Komu

行ごとに「翻訳」できます。

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):
0
Fire Lancer

Python3の場合と2つのリスト

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)
0

次を使用できます。

b=['E', 'P', 'P', 'E', 'O', 'E']
c={}
for i in b:
    value=0
    for j in b:
        if(i == j):
            value+=1
            c[i]=value
print(c)

出力:

{'E': 3, 'P': 2, 'O': 1}
0
Prince Vijay