2017-05-17 63 views
6

Merhaba, python'da iki listeye sahip olduğumu ve her iki listeden de ortak değerleri kaldırmak istediğimizi varsayalım. Potansiyel bir çözümdür: Doğru görünüyor ama değilPython'daki iki listeden ortak değerleri kaldırma

x = [1, 2, 3, 4, 5, 6, 7, 8] 
y = [43, 3123, 543, 76, 879, 32, 14241, 342, 2, 3, 4] 
for i in x: 
    if i in y: 
     x.remove(i) 
     y.remove(i) 

. Nedeni, sanırım, listeden bir öğeyi kaldırarak dizin yinelenmeye devam ediyor. Bu nedenle, değerlerin birbirine yakın olduğu listelerdeki iki ortak değer için, daha sonraki değerleri kaçırmayacağız (kod, üzerinde yineleme yapmayacaktır). sonucu olacaktır:

>>> x 
[1, 3, 5, 6, 8, 9, 10] 
>>> y 
[43, 3123, 543, 76, 879, 32, 14241, 342, 3] 

yüzden değerini '3' eksik.

Bu davranışın nedeni, bahsettiğim şey mi? Yoksa yanlış bir şey mi yapıyorum?

+0

Evet, bu, üzerinde yineleme yaparken bir nesneyi değiştirerek karşılaşacağınız problemdir. –

+0

Lütfen bu soruya bir göz atın: [Yinelenen bir listeden öğeleri kaldırın] (https://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating) – direprobs

+0

Kesinlikle tavsiye edilmez Yinelediğiniz değeri değiştirin. Bu, kodunuzun ne yaptığını anlamaya çalışan herkes için döngü akışını belirlemeyi zorlaştırabilir. Bu gibi durumlarda genellikle listenizin (veya başka bir yinelenen nesnenin) ayrı bir kopyasında değişiklik yapılması veya listeye dilimlenmesi için bir indeks üzerinde yineleme yapılması önerilir: 'menzil için i (len (x)): print (x [i]) ' – Aaron

cevap

8

Sadece küçük bir değişiklik kodunuzu Denemeleri:

x, y = np.setdiff1d(x, y), np.setdiff1d(y, x) 

ve numpy kullanmak istemiyorsanız x x[:].Onun üzerinde yineleme yaparken listeyi değiştiriyorsunuz. Eğer değer 3

for i in x[:]: 
     if i in y: 
      x.remove(i) 
      y.remove(i) 

Ve alternatif bir yöntem

x,y = [i for i in x if i not in y],[j for j in y if j not in x] 
+0

Herhangi bir listede çoğaltılmış bir değer varsa işe yaramazsa, şunu deneyin: 'x = [1, 2, 3, 4, 5, 6, 7, 8, 3]' ayrıca y kopyasını da – DSLima90

+0

@ DSLima90 Bence OP gerekliliğine kadar, tüm yinelenen yinelemeyi kaldırmak istiyorsa işe yaramıyor. Ancak her iki listeden silindikten sonra ilk listede benzersiz hale getirilmiştir. Yani bu bir sorun değil. –

+0

@Rhaul Evet, haklısınız. OP'nin, sağlanan tüm kodları yorumlayarak tüm olayları silmek istediğini varsaydım. Bu geçerli bir cevaptır, yine de şu ana kadar bu yönde diğer cevaplardan farklı olduğunu belirtmek gerekir. – DSLima90

3
z=[i for i in x if i not in y] 
w=[i for i in y if i not in x] 
x=z 
y=w 

Bu hile yapmalı mı? Biraz daha az hafıza etkin. Eğer numpy kullanırsanız

+0

evet, sonunda yaptım. Teşekkürler – MaPy

+0

Bu, x, y = [i'de x için i'de değil], [i'de x için değil] için yoğunlaştırılabilir. –

2

, o zaman ihtiyacınız olan: didik,

x, y = list(set(x).difference(y)), list(set(y).difference(x)) 
6

Ayrıca set nesnelerin farkını kullanabilirsiniz eksik nedeni bu.

a = list(set(y) - set(x)) 
b = list(set(x) - set(y)) 
+0

ile güncelleştirilir. Bunun bir dezavantajı, tüm yinelenen öğeleri kaldıracak ve siparişi kaybedecek olmasıdır. Ama genellikle bunu yapmak isteyen insanlar için sorun değil – abccd

1

Ben şahsen Python'un set veri türü gitmek için yol olduğunu düşünüyorum:

Böyle bir şey yapabilirsiniz:

>>> x = [1, 2, 3, 4, 5, 6, 7, 8] 
>>> y = [43, 3123, 543, 76, 879, 32, 14241, 342, 2, 3, 4] 
>>> sx = set(x) 
>>> sy = set(y) 
>>> sx.union(sy) 
set([1, 2, 3, 4, 5, 6, 7, 8, 32, 43, 76, 342, 543, 879, 3123, 14241]) 

Yoksa bir tek astar bunu azaltabilir:

list(set(x).union(set(y)))