2017-05-17 18 views
6

Hi sagen wir, ich habe zwei Listen in Python und ich möchte gemeinsame Werte aus beiden Listen entfernen. Eine mögliche Lösung ist:Entfernen von gemeinsamen Werten aus zwei Listen in Python

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) 

scheint es richtig, aber es ist nicht. Der Grund liegt vermutlich darin, dass der Index durch das Entfernen eines Elements aus der Liste weiter iteriert. Daher werden für zwei gemeinsame Werte in den Listen, in denen die Werte nahe beieinander liegen, die späteren Werte fehlen (der Code wird nicht iterieren). Das Ergebnis wäre:

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

So fehlen wir den Wert '3'.

Ist der Grund für dieses Verhalten der, den ich erwähnt habe? oder mache ich etwas anderes falsch?

+0

Ja, dies ist genau das Problem, dem Sie begegnen werden, wenn Sie ein Objekt ändern, während Sie darüber iterieren. –

+0

Bitte werfen Sie einen Blick auf diese Frage: [Entfernen Sie Elemente aus einer Liste beim Iterieren] (https://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating) – direprobs

+0

Es wird dringend davon abgeraten Ändere den Wert, den du wiederholst. Dies kann es schwierig machen, den Fluss der Schleife für jeden zu bestimmen, der versucht zu verstehen, was der Code tut. In solchen Fällen ist es normalerweise ratsam, Änderungen an einer separaten Kopie Ihrer Liste (oder eines anderen iterierbaren Objekts) vorzunehmen oder über einen Index zu iterieren, um in Ihre Liste zu schneiden: 'für i im Bereich (len (x)): print (x [i]) ' – Aaron

Antwort

8

nur geringfügige Änderung der Code, eine Iteration durch die Kopie von x ist es x[:]. Sie ändern die Liste, während Sie darüber iterieren. Also das ist, warum Sie Wert fehlen 3

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

und alternative Methode

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

Das funktioniert nicht, wenn es in einer Liste einen doppelten Wert gibt, versuchen Sie: 'x = [1, 2, 3, 4, 5, 6, 7, 8, 3]' Sie müssen auch eine Kopie von y machen – DSLima90

+0

@ DSLima90 Ich denke, dass bis zur OP-Anforderung, Wenn er alle Vorkommen von Duplikat entfernen will, wird es nicht funktionieren. Aber nach dem Löschen von beiden Listen ist es einzigartig in der ersten Liste. Das ist also kein Problem. –

+0

@Rhaul Ja, du hast Recht. Ich ging davon aus, dass OP alle Vorkommen durch meine Interpretation des bereitgestellten Codes löschen möchte. Es ist eine gültige Antwort, obwohl es vielleicht erwähnenswert ist, dass es sich von den anderen Antworten in diesem Aspekt bisher unterscheidet. – 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 

Das sollte den Trick tun? Es ist ein bisschen weniger Speicher effizient.

+0

ja das ist, was ich am Ende gemacht habe. Danke – MaPy

+0

Dies kann zu "x, y = [i für i in x, wenn ich nicht in y], [i für i in y, wenn ich nicht in x]" kondensiert werden. –

2

Wenn Sie numpy verwenden, dann alles, was Sie brauchen, ist:

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

und wenn Sie nicht wollen, numpy verwenden:

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

Sie auch Unterschied von set Objekte verwenden können.

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

aktualisiert Ein Nachteil davon ist, dass es alle doppelten Artikel entfernt und die Bestellung verliert. Aber normalerweise ist es für Leute, die dies tun wollen, kein Problem – abccd

1

Ich persönlich denke, set Datentyp Python der Weg zu gehen ist:

Sie können etwas tun:

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

Oder Sie es zu einem Einzeiler reduzieren:

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