繰り返し要素を持つことができる正の整数の 2 つの並べ替えられたリストがあり、一致する数値のペアを各リストから 1 つずつ削除する必要があります。
a=[1,2,2,2,3]
b=[2,3,4,5,5]
なる必要があります:
a=[1,2,2]
b=[4,5,5]
つまり、2 と 3 は両方のリストに表示されるため、削除されています。
要素が繰り返されるため、ここでは集合交差を使用できません。
どうすればいいですか?
両方のリストに表示される要素を削除するには、次を使用します。
for i in a[:]:
if i in b:
a.remove(i)
b.remove(i)
それを行う関数を作成するには、次のようにします。
def removeCommonElements(a, b):
for e in a[:]:
if e in b:
a.remove(e)
b.remove(e)
または、古いリストを編集せずに新しいリストを返すには:
def getWithoutCommonElements(a, b): # Name subject to change
a2 = a.copy()
b2 = b.copy()
for e in a:
if e not in b:
a2.remove(e)
b2.remove(e)
return a2, b2
ただし、前者は次のように置き換えることができますremoveCommonElements
。
a2, b2 = a.copy(), b.copy()
removeCommonElements(a2, b2)
これは a と b を保持しますが、共通要素のない重複を作成します。
リストがソートされている場合、次のように要素ごとにマージ/配布できます。
x, y = [], []
while a and b:
if a[0] < b[0]:
x.append(a.pop(0))
elif a[0] > b[0]:
y.append(b.pop(0))
else: # a[0]==b[0]
a.pop(0)
b.pop(0)
x += a
y += b
コレクションの Counter オブジェクトは、これを非常に簡潔に行うことができます。
from collections import Counter
a=Counter([1,2,2,2,3])
b=Counter([2,3,4,5,5])
print list((a-b).elements())
print list((b-a).elements())
アイデアは次のとおりです。
(警告: 出力リストは必ずしもソートされるとは限りません)
@Mahi によって与えられた解決策はほぼ正しいです。あなたが望むものを達成する最も簡単な方法はこれです:
def remove_common_elements(a, b):
for i in a[:]:
if i in b:
a.remove(i)
b.remove(i)
return a, b
ここで重要なのは、書き写すa
ことa[:]
です。リストから要素を削除しながらリストを反復すると、正しい結果が得られません。
その場でリストを変更したくない場合は、事前に両方のリストのコピーを作成し、コピーしたリストを返します。
def remove_common_elements(a, b):
a_new = a[:]
b_new = b[:]
for i in a:
if i in b_new:
a_new.remove(i)
b_new.remove(i)
return a_new, b_new
1 つの解決策は、a の新しいコピーを作成し、b から共通要素を削除することです。
a = [1,2,2,2,3]
b = [2,2,3,4,5]
a_new = []
for ai in a:
if ai in b:
b.remove(ai)
else:
a_new.append(ai)
print a_new
print b