2016-06-16 8 views
3

Ich habe eine übergeordnete Liste namens parent_list, und zwei Teilmengen, über die ich die parent_list filtern soll. Diese Subsets sind auch Python-Listen und heißen filter1 und filter2.So entfernen Sie ein Element aus einer Liste, wenn es in einer oder zwei (oder N) anderen Listen

Kann ich tun:

final_list = [object for object in parent_list if object.pk not in filter1 or filter2] 

Oder muss ich diese filteration separat tun, wie in:

intermediate_list = [object for object in parent_list if object.pk not in filter1] 
final_list = [object for object in intermediate_list if object.pk not in filter2] 

ich nicht explizit die Antwort aus der Dokumentation über python Listenkomprehensionen finden konnten, .

Antwort

6

verwenden Sets für die schnelle nachschlagen der Einzelteile:

final_list = [object for object in parent_list if object.pk not in set(filter1 + filter2)] 
#                 ^

Die Größe des gesamten Suchbereichs wird ebenfalls reduziert, wenn doppelte Elemente aus dem Satz entfernt werden.

diese somewhere auf SO Gefunden:

Sets implementiert Hash-Tabellen. Wenn Sie ein Objekt zu einer Menge hinzufügen, wird die Position innerhalb des Speichers des Mengenobjekts mit dem Hash des hinzuzufügenden Objekts bestimmt. Beim Testen auf Mitgliedschaft, alles, was getan werden muss, ist im Grunde zu sehen, ob das Objekt an der Position durch seinen Hash festgelegt ist, so dass die Geschwindigkeit dieser Operation nicht von der Größe des Satzes abhängen. Bei Listen muss dagegen die gesamte -Liste durchsucht werden, die mit wachsender Liste langsamer wird.

+0

Zwei weitere Fragen: ** 1) ** muss ich das Set in eine Liste konvertieren (dh Liste (set (filter1 + filter2)), damit dies funktioniert ** 2) ** diese Art von etwas gewonnen ' t arbeiten mit ValuesQuerySet würde es? –

+2

Erzwingen Sie, dass die QuerySets ihre Elemente durch Slicing auswerten: 'set (filter1 [:] + filter2 [:])'. Sie müssen das 'set' nicht in eine' list' konvertieren. –

1

Ich glaube, Sie es wie unten tun können:

final_list = [object for object in parent_list if (object.pk not in filter1) and (object.pk not in filter2)] 

Ich empfehle zwei Sätze filter1 und filter2 mit dem object.pk machen nur gefiltert werden bc ein Element aus einem Satz immer schneller, es ist

+0

Ich denke, Sie möchten 'und', nicht 'oder' verwenden. –

+0

John Gordon @ Danke dude ich habe korrigiert –

+0

Dank Mahendra, gehen mit Moses 'Antwort auf diesem einen da es einige zusätzliche Optimierung in sich hatte. –

1

können Sie auch verwenden:

final_list = [object for object in parent_list if object.pk not in filter1+filter2] 
+1

Dank Nikign, geht mit Moses auf diesem. –