Löschen mehrerer Elemente aus einer Liste

160

Ist es möglich, mehrere Elemente gleichzeitig aus einer Liste zu löschen? Wenn ich Elemente bei Index 0 und 2 löschen und etwas wie versuchen möchte del somelist[0], gefolgt von del somelist[2], wird die zweite Anweisung tatsächlich gelöscht somelist[3].

Ich denke, ich könnte immer zuerst die höher nummerierten Elemente löschen, aber ich hoffe, es gibt einen besseren Weg.

Løiten
quelle

Antworten:

110

Wahrscheinlich nicht die beste Lösung für dieses Problem:

indices = 0, 2
somelist = [i for j, i in enumerate(somelist) if j not in indices]
SilentGhost
quelle
2
Fast nur, wenn Sie die gesamte Liste löschen. es wird len (Indizes) * len (Somelist) sein. Es wird auch eine Kopie erstellt, die erwünscht sein kann oder nicht
Richard Levasseur
Wenn Sie in einer Liste nach einem Wert suchen, ist dies der Fall. Der Operator 'in' arbeitet mit den Werten einer Liste, während er mit den Tasten eines Diktats arbeitet. Wenn ich falsch liege, verweise mich bitte auf den Hinweis / Referenz
Richard Levasseur
5
Der Grund, warum ich Tupel für Indizes gewählt habe, war nur die Einfachheit des Datensatzes. Es wäre ein perfekter Job, um set () O (n)
SilentGhost zu geben
18
Dabei werden keine Elemente aus einer Liste gelöscht, sondern eine brandneue Liste erstellt. Wenn irgendetwas einen Verweis auf die ursprüngliche Liste enthält, enthält es immer noch alle Elemente.
Tom Future
2
@SilentGhost Keine Aufzählung erforderlich. Wie wäre es damit : somelist = [ lst[i] for i in xrange(len(lst)) if i not in set(indices) ]?
ToolmakerSteve
183

Aus irgendeinem Grund mag ich keine der Antworten hier. Ja, sie funktionieren, aber genau genommen löschen die meisten von ihnen keine Elemente in einer Liste, oder? (Erstellen Sie jedoch eine Kopie und ersetzen Sie die Originalkopie durch die bearbeitete Kopie.)

Warum nicht einfach zuerst den höheren Index löschen?

Gibt es einen Grund dafür? Ich würde einfach tun:

for i in sorted(indices, reverse=True):
    del somelist[i]

Wenn Sie Elemente wirklich nicht rückwärts löschen möchten, sollten Sie die Indexwerte, die größer als der zuletzt gelöschte Index sind (Sie können nicht denselben Index verwenden, da Sie eine andere Liste haben), einfach inkrementieren oder verwenden eine Kopie der Liste (die nicht "löschen", sondern das Original durch eine bearbeitete Kopie ersetzen würde).

Vermisse ich hier etwas, einen Grund, NICHT in umgekehrter Reihenfolge zu löschen?

Tglaria
quelle
1
Ich weiß nicht, warum dies nicht als akzeptierte Antwort gewählt wurde!. Danke dafür.
Swathis
4
Es gibt zwei Gründe. (a) Bei einer Liste wäre die zeitliche Komplexität im Durchschnitt höher als bei der Methode "Kopie erstellen" (unter Verwendung eines Satzes von Indizes) (unter der Annahme zufälliger Indizes), da einige Elemente mehrmals nach vorne verschoben werden müssen. (b) Zumindest für mich ist es schwer zu lesen, da es eine Sortierfunktion gibt, die keiner tatsächlichen Programmlogik entspricht und nur aus technischen Gründen existiert. Obwohl ich die Logik bereits gründlich verstehe, habe ich immer noch das Gefühl , dass es schwierig sein würde, sie zu lesen.
Unverderbliche Nacht
1
@ImperishableNight Könnten Sie (a) näher erläutern? Ich verstehe nicht, dass "einige Elemente verschoben werden müssen". Für (b) können Sie einfach eine Funktion definieren, wenn Sie Leseklarheit benötigen.
Tglaria
109

Wenn Sie mehrere nicht benachbarte Elemente löschen, ist das, was Sie beschreiben, der beste Weg (und ja, beginnen Sie unbedingt mit dem höchsten Index).

Wenn Ihre Elemente nebeneinander liegen, können Sie die Slice-Zuweisungssyntax verwenden:

a[2:10] = []
Greg Hewgill
quelle
95
Sie können auch del a[2:10]mit dem gleichen Effekt sagen .
etw
8
@sth Interessanterweise ist del etwas schneller als die Zuweisung.
thefourtheye
24

Sie können numpy.deletewie folgt verwenden:

import numpy as np
a = ['a', 'l', 3.14, 42, 'u']
I = [0, 2]
np.delete(a, I).tolist()
# Returns: ['l', '42', 'u']

Wenn es Ihnen nichts ausmacht, numpyam Ende ein Array zu haben, können Sie das weglassen .tolist(). Sie sollten auch einige ziemlich große Geschwindigkeitsverbesserungen sehen, was diese Lösung skalierbarer macht. Ich habe es nicht bewertet, aber numpyOperationen sind kompilierter Code, der entweder in C oder Fortran geschrieben ist.

philE
quelle
1
allgemeine Lösung, wenn Elemente nicht aufeinander
folgen
1
Frage hier, wie wäre es mit dem Löschen von ['a', 42].
Evanshutomo
RIESIGE Bonuspunkte für diese Lösung im Vergleich zu den anderen für die Geschwindigkeit. Was ich sagen kann ist, dass ich für einen sehr großen Datensatz einige Minuten gebraucht habe, um etwas zu erreichen, das mit guter alter Zahl nur wenige Sekunden dauerte.
Legel
18

Als Spezialisierung von Gregs Antwort können Sie sogar die erweiterte Slice-Syntax verwenden. z.B. Wenn Sie die Elemente 0 und 2 löschen möchten:

>>> a= [0, 1, 2, 3, 4]
>>> del a[0:3:2]
>>> a
[1, 3, 4]

Dies deckt natürlich keine willkürliche Auswahl ab, kann aber durchaus zum Löschen von zwei beliebigen Elementen verwendet werden.

Bobince
quelle
16

Als eine Funktion:

def multi_delete(list_, *args):
    indexes = sorted(list(args), reverse=True)
    for index in indexes:
        del list_[index]
    return list_

Läuft in n log (n) Zeit, was es zur schnellsten richtigen Lösung machen sollte.

Nikhil Chelliah
quelle
1
Die Version mit args.sort (). Reverse () ist definitiv besser. Es funktioniert auch mit Diktaten, anstatt zu werfen oder, schlimmer noch, stillschweigend zu korrumpieren.
sort () ist nicht für Tupel definiert, Sie müssen zuerst in list konvertieren. sort () gibt None zurück, sodass Sie reverse () nicht verwenden können.
SilentGhost
@ R. Pate: Ich habe die erste Version aus diesem Grund entfernt. Vielen Dank. @ SilentGhost: Es wurde behoben.
Nikhil Chelliah
@Nikhil: Nein, hast du nicht;) args = list (args) args.sort () args.reverse (), aber die bessere Option wäre: args = sortiert (args, reverse = True)
SilentGhost
2
n log n? "Ja wirklich?" Ich glaube nicht, dass del list[index]es O (1) ist.
user202729
12

Sie möchten also im Wesentlichen mehrere Elemente in einem Durchgang löschen? In diesem Fall wird die Position des nächsten zu löschenden Elements um die Anzahl der zuvor gelöschten Elemente versetzt.

Unser Ziel ist es, alle Vokale zu löschen, die als Indizes 1, 4 und 7 vorberechnet wurden. Beachten Sie, dass die to_delete-Indizes in aufsteigender Reihenfolge wichtig sind, da sie sonst nicht funktionieren.

to_delete = [1, 4, 7]
target = list("hello world")
for offset, index in enumerate(to_delete):
  index -= offset
  del target[index]

Es wäre komplizierter, wenn Sie die Elemente in beliebiger Reihenfolge löschen möchten. IMO, das Sortieren ist to_deletemöglicherweise einfacher, als herauszufinden, wann Sie subtrahieren sollten oder nicht index.

Richard Levasseur
quelle
8

Ich bin ein absoluter Anfänger in Python, und meine Programmierung ist im Moment, gelinde gesagt, grob und schmutzig, aber meine Lösung bestand darin, eine Kombination der grundlegenden Befehle zu verwenden, die ich in frühen Tutorials gelernt habe:

some_list = [1,2,3,4,5,6,7,8,10]
rem = [0,5,7]

for i in rem:
    some_list[i] = '!' # mark for deletion

for i in range(0, some_list.count('!')):
    some_list.remove('!') # remove
print some_list

Dies hat natürlich seine Grenzen, da ein Zeichen zum Löschen markiert werden muss.

Was die Leistung angeht, da die Größe der Liste skaliert, bin ich sicher, dass meine Lösung nicht optimal ist. Es ist jedoch unkompliziert, was hoffentlich andere Anfänger anspricht, und funktioniert in einfachen Fällen, in denen some_listes ein bekanntes Format hat, z. B. immer numerisch ...

Paul
quelle
2
anstatt '!' Verwenden Sie als Ihren besonderen Charakter None. Dies hält jeden Charakter gültig und macht Ihre Möglichkeiten frei
portforwardpodcast
5

Hier ist eine Alternative, bei der enumerate () nicht zum Erstellen von Tupeln verwendet wird (wie in der ursprünglichen Antwort von SilentGhost).

Dies scheint mir lesbarer zu sein. (Vielleicht würde ich mich anders fühlen, wenn ich es gewohnt wäre, Aufzählungen zu verwenden.) CAVEAT: Ich habe die Leistung der beiden Ansätze nicht getestet.

# Returns a new list. "lst" is not modified.
def delete_by_indices(lst, indices):
    indices_as_set = set(indices)
    return [ lst[i] for i in xrange(len(lst)) if i not in indices_as_set ]

HINWEIS: Python 2.7-Syntax. Für Python 3 xrange=>range .

Verwendung:

lst = [ 11*x for x in xrange(10) ]
somelist = delete_by_indices( lst, [0, 4, 5])

Somelist:

[11, 22, 33, 66, 77, 88, 99]

--- BONUS ---

Löschen Sie mehrere Werte aus einer Liste. Das heißt, wir haben die Werte, die wir löschen möchten:

# Returns a new list. "lst" is not modified.
def delete__by_values(lst, values):
    values_as_set = set(values)
    return [ x for x in lst if x not in values_as_set ]

Verwendung:

somelist = delete__by_values( lst, [0, 44, 55] )

Somelist:

[11, 22, 33, 66, 77, 88, 99]

Dies ist die gleiche Antwort wie zuvor, aber diesmal haben wir die zu löschenden WERTE angegeben [0, 44, 55].

ToolmakerSteve
quelle
Ich habe entschieden, dass @ SilentGhost's nur schwer zu lesen ist, da für das Ergebnis der Aufzählung nicht beschreibende Variablennamen verwendet werden. Auch Parens hätten das Lesen erleichtert. Also hier ist, wie ich seine Lösung formulieren würde (mit "set" für die Leistung) : [ value for (i, value) in enumerate(lst) if i not in set(indices) ]. Aber ich werde meine Antwort hier lassen, weil ich auch zeige, wie man nach Werten löscht. Das ist ein einfacher Fall, könnte aber jemandem helfen.
ToolmakerSteve
@ Veedrac- danke; Ich habe neu geschrieben, um das Set zuerst zu erstellen. Was denkst du - schnellere Lösung als die von SilentGhost? (Ich halte es nicht für wichtig genug, um es tatsächlich zu planen, sondern frage nur nach Ihrer Meinung.) Ebenso würde ich die Version von SilentGhost als neu schreibenindices_as_set = set(indices) , [ value for (i, value) in enumerate(lst) if i not in indices_as_set ]es zu beschleunigen.
ToolmakerSteve
Gibt es einen Stilgrund für den doppelten Unterstrich delete__by_values()?
Tom
5

Eine alternative Methode zum Verständnis von Listen, die Listenindexwerte verwendet:

stuff = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
index = [0, 3, 6]
new = [i for i in stuff if stuff.index(i) not in index]

Dies gibt zurück:

['b', 'c', 'e', 'f']
Miau
quelle
Gute Antwort, aber die Liste der Indizes als indexirreführend zu bezeichnen, da im Listeniterator die Methode verwendet wirdindex()
Joe
4

Hier ist eine andere Methode, mit der die Elemente entfernt werden. Auch wenn Ihre Liste wirklich lang ist, ist sie schneller.

>>> a = range(10)
>>> remove = [0,4,5]
>>> from collections import deque
>>> deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)

>>> timeit.timeit('[i for j, i in enumerate(a) if j not in remove]', setup='import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.1704120635986328

>>> timeit.timeit('deque((list.pop(a, i) for i in sorted(remove, reverse=True)), maxlen=0)', setup='from collections import deque;import random;remove=[random.randrange(100000) for i in range(100)]; a = range(100000)', number=1)
0.004853963851928711
user545424
quelle
+1: Interessante Verwendung von deque, um eine for-Aktion als Teil eines Ausdrucks auszuführen, anstatt einen "for ..:" - Block zu benötigen. Für diesen einfachen Fall finde ich Nikhils für Block jedoch besser lesbar.
ToolmakerSteve
4

Dies wurde erwähnt, aber irgendwie hat es niemand geschafft, es richtig zu machen.

Eine O(n)Lösung wäre:

indices = {0, 2}
somelist = [i for j, i in enumerate(somelist) if j not in indices]

Dies kommt der Version von SilentGhost sehr nahe , fügt jedoch zwei geschweifte Klammern hinzu.

Veedrac
quelle
Dies ist nicht O(n)der Fall, wenn Sie die Suchvorgänge zählen, die log(len(indices))für jede Iteration erforderlich sind.
Mad Physicist
@ MadPhysicist j not in indicesist O(1).
Veedrac
Ich bin nicht sicher, wie Sie diese Nummer bekommen. Da Indizes eine Menge sind, ist j not in indicesimmer noch eine Suche erforderlich O(log(len(indices))). Ich bin zwar damit einverstanden, dass eine Suche in einem 2-Elemente-Satz als qualifiziert gilt O(1), im allgemeinen Fall jedoch O(log(N)). So oder so O(N log(N))schlägt immer noch O(N^2).
Verrückter Physiker
3
@ MadPhysicist j not in indicesist O(1)im Ernst.
Veedrac
Und was genau haben zwei Zahnspangen gemacht?
Nuclear03020704
4
l = ['a','b','a','c','a','d']
to_remove = [1, 3]
[l[i] for i in range(0, len(l)) if i not in to_remove])

Es ist im Grunde das Gleiche wie die am häufigsten gewählte Antwort, nur eine andere Art, sie zu schreiben. Beachten Sie, dass die Verwendung von l.index () keine gute Idee ist, da doppelte Elemente in einer Liste nicht verarbeitet werden können.

Zink
quelle
2

Die Methode "Entfernen" führt zu einer starken Verschiebung der Listenelemente. Ich denke, es ist besser, eine Kopie zu machen:

...
new_list = []
for el in obj.my_list:
   if condition_is_true(el):
      new_list.append(el)
del obj.my_list
obj.my_list = new_list
...
luca
quelle
2

Technisch gesehen lautet die Antwort NEIN. Es ist nicht möglich, zwei Objekte gleichzeitig zu löschen. Es ist jedoch möglich, zwei Objekte in einer Zeile schöner Python zu löschen.

del (foo['bar'],foo['baz'])

wird recusrively löschen foo['bar'], dannfoo['baz']

David Brilliant
quelle
Dies wird aus einem Diktierobjekt gelöscht, nicht aus einer Liste, aber ich bin immer noch dabei, weil es verdammt hübsch ist!
Ulf Aslak
Dies gilt auch für Listen mit der entsprechenden Syntax. Die Behauptung, dass es nicht möglich ist, zwei Objekte gleichzeitig zu löschen, ist jedoch falsch. siehe Antwort von @bobince
Pedro Gimeno
2

Wir können dies tun, indem wir eine for-Schleife verwenden, die über die Indizes iteriert, nachdem die Indexliste in absteigender Reihenfolge sortiert wurde

mylist=[66.25, 333, 1, 4, 6, 7, 8, 56, 8769, 65]
indexes = 4,6
indexes = sorted(indexes, reverse=True)
for i in index:
    mylist.pop(i)
print mylist
Gourav Singla
quelle
2

Für die Indizes 0 und 2 aus Liste A:

for x in (2,0): listA.pop(x)

Für einige zufällige Indizes, die aus listA entfernt werden sollen:

indices=(5,3,2,7,0) 
for x in sorted(indices)[::-1]: listA.pop(x)
Marmelade
quelle
2

Ich wollte einen Weg finden, die verschiedenen Lösungen zu vergleichen, die es einfach machten, die Knöpfe zu drehen.

Zuerst habe ich meine Daten generiert:

import random

N = 16 * 1024
x = range(N)
random.shuffle(x)
y = random.sample(range(N), N / 10)

Dann habe ich meine Funktionen definiert:

def list_set(value_list, index_list):
    index_list = set(index_list)
    result = [value for index, value in enumerate(value_list) if index not in index_list]
    return result

def list_del(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        del(value_list[index])

def list_pop(value_list, index_list):
    for index in sorted(index_list, reverse=True):
        value_list.pop(index)

Dann habe ich timeitdie Lösungen verglichen:

import timeit
from collections import OrderedDict

M = 1000
setup = 'from __main__ import x, y, list_set, list_del, list_pop'
statement_dict = OrderedDict([
    ('overhead',  'a = x[:]'),
    ('set', 'a = x[:]; list_set(a, y)'),
    ('del', 'a = x[:]; list_del(a, y)'),
    ('pop', 'a = x[:]; list_pop(a, y)'),
])

overhead = None
result_dict = OrderedDict()
for name, statement in statement_dict.iteritems():
    result = timeit.timeit(statement, number=M, setup=setup)
    if overhead is None:
        overhead = result
    else:
        result = result - overhead
        result_dict[name] = result

for name, result in result_dict.iteritems():
    print "%s = %7.3f" % (name, result)

Ausgabe

set =   1.711
del =   3.450
pop =   3.618

Der Generator mit den Indizes in a setwar also der Gewinner. Und delist dann etwas schneller pop.

David Cullen
quelle
Vielen Dank für diesen Vergleich. Dies hat mich dazu veranlasst, meine eigenen Tests durchzuführen (tatsächlich nur Ihren Code ausgeliehen). Für eine geringe Anzahl von Elementen, die entfernt werden müssen, ist der Aufwand für die Erstellung eines SET die schlechteste Lösung (verwenden Sie 10, 100, 500 für die Länge von 'y' und du wirst sehen). Wie in den meisten Fällen hängt dies von der Anwendung ab.
Tglaria
2

Sie können diese Logik verwenden:

my_list = ['word','yes','no','nice']

c=[b for i,b in enumerate(my_list) if not i in (0,2,3)]

print c
Raghu
quelle
2

Eine weitere Umsetzung der Idee, aus dem höchsten Index zu entfernen.

for i in range(len(yourlist)-1, -1, -1):
    del yourlist(i)
ipramusinto
quelle
1

Ich kann mir zwei Möglichkeiten vorstellen:

  1. Schneiden Sie die Liste wie folgt auf (dies löscht das 1., 3. und 8. Element)

    Somelist = Somelist [1: 2] + Somelist [3: 7] + Somelist [8:]

  2. Tun Sie das an Ort und Stelle, aber nacheinander:

    somelist.pop (2) somelist.pop (0)

Bartosz Radaczyński
quelle
1

Sie können dies auf einem Diktat tun, nicht auf einer Liste. In einer Liste sind die Elemente der Reihe nach. In einem Diktat hängen sie nur vom Index ab.

Einfacher Code, um es zu erklären, indem Sie Folgendes tun :

>>> lst = ['a','b','c']
>>> dct = {0: 'a', 1: 'b', 2:'c'}
>>> lst[0]
'a'
>>> dct[0]
'a'
>>> del lst[0]
>>> del dct[0]
>>> lst[0]
'b'
>>> dct[0]
Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    dct[0]
KeyError: 0
>>> dct[1]
'b'
>>> lst[1]
'c'

Eine Möglichkeit, eine Liste in ein Diktat zu "konvertieren", ist:

>>> dct = {}
>>> for i in xrange(0,len(lst)): dct[i] = lst[i]

Das Gegenteil ist:

lst = [dct[i] for i in sorted(dct.keys())] 

Wie auch immer, ich denke, es ist besser, mit dem Löschen aus dem höheren Index zu beginnen, wie Sie sagten.

Andrea Ambu
quelle
Garantiert Python, dass [dct [i] für i in dct] immer steigende Werte von i verwendet? Wenn ja, ist list (dct.values ​​()) sicherlich besser.
Daran habe ich nicht gedacht. Du hast recht. Es gibt keine Garantie, wenn ich [hier] [1] lese, dass die Artikel in der richtigen Reihenfolge oder zumindest in der erwarteten Reihenfolge kommissioniert werden. Ich habe bearbeitet. [1]: docs.python.org/library/stdtypes.html#dict.items
Andrea Ambu
2
Diese Antwort spricht grundlegend falsch über Wörterbücher. Ein Wörterbuch hat SCHLÜSSEL (keine INDIZES). Ja, die Schlüssel / Wert-Paare sind unabhängig voneinander. Nein, es spielt keine Rolle, in welcher Reihenfolge Sie die Einträge löschen. Das Konvertieren in ein Wörterbuch, nur um einige Elemente aus einer Liste zu löschen, wäre übertrieben.
ToolmakerSteve
1

Um den Kommentar von @sth zu verallgemeinern . Das Löschen von Elementen in jeder Klasse, die abc.MutableSequence implementiert , und listinsbesondere erfolgt über die __delitem__magische Methode. Diese Methode funktioniert ähnlich wie __getitem__, dh sie kann entweder eine Ganzzahl oder ein Slice akzeptieren. Hier ist ein Beispiel:

class MyList(list):
    def __delitem__(self, item):
        if isinstance(item, slice):
            for i in range(*item.indices(len(self))):
                self[i] = 'null'
        else:
            self[item] = 'null'


l = MyList(range(10))
print(l)
del l[5:8]
print(l)

Dies wird ausgegeben

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 'null', 'null', 'null', 8, 9]
Alexander Zhukov
quelle
1

Das Importieren nur aus diesem Grund ist möglicherweise übertrieben, aber wenn Sie es pandastrotzdem verwenden, ist die Lösung einfach und unkompliziert:

import pandas as pd
stuff = pd.Series(['a','b','a','c','a','d'])
less_stuff = stuff[stuff != 'a']  # define any condition here
# results ['b','c','d']
Lorinc Nyitrai
quelle
1
some_list.remove(some_list[max(i, j)])

Vermeidet das Sortieren von Kosten und das explizite Kopieren der Liste.

Chester
quelle
0

Wie wäre es mit einem davon (ich bin sehr neu in Python, aber sie scheinen in Ordnung zu sein):

ocean_basin = ['a', 'Atlantic', 'Pacific', 'Indian', 'a', 'a', 'a']
for i in range(1, (ocean_basin.count('a') + 1)):
    ocean_basin.remove('a')
print(ocean_basin)

['Atlantik', 'Pazifik', 'Indianer']

ob = ['a', 'b', 4, 5,'Atlantic', 'Pacific', 'Indian', 'a', 'a', 4, 'a']
remove = ('a', 'b', 4, 5)
ob = [i for i in ob if i not in (remove)]
print(ob)

['Atlantik', 'Pazifik', 'Indianer']

user12001090
quelle
0

Keine der bisher angebotenen Antworten führt das Löschen in O (n) auf der Länge der Liste durch, damit eine beliebige Anzahl von Indizes gelöscht werden kann. Hier ist meine Version:

def multi_delete(the_list, indices):
    assert type(indices) in {set, frozenset}, "indices must be a set or frozenset"
    offset = 0
    for i in range(len(the_list)):
        if i in indices:
            offset += 1
        elif offset:
            the_list[i - offset] = the_list[i]
    if offset:
        del the_list[-offset:]

# Example:
a = [0, 1, 2, 3, 4, 5, 6, 7]
multi_delete(a, {1, 2, 4, 6, 7})
print(a)  # prints [0, 3, 5]
Pedro Gimeno
quelle
0

Sie können auch remove verwenden.

delete_from_somelist = []
for i in [int(0), int(2)]:
     delete_from_somelist.append(somelist[i])
for j in delete_from_somelist:
     newlist = somelist.remove(j)
Jiwon Kim
quelle
0

Ich habe alles zu einer list_diffFunktion zusammengefasst, die einfach zwei Listen als Eingaben verwendet und deren Differenz zurückgibt, wobei die ursprüngliche Reihenfolge der ersten Liste beibehalten wird.

def list_diff(list_a, list_b, verbose=False):

    # returns a difference of list_a and list_b,
    # preserving the original order, unlike set-based solutions

    # get indices of elements to be excluded from list_a
    excl_ind = [i for i, x in enumerate(list_a) if x in list_b]
    if verbose:
        print(excl_ind)

    # filter out the excluded indices, producing a new list 
    new_list = [i for i in list_a if list_a.index(i) not in excl_ind]
    if verbose:
        print(new_list)

    return(new_list)

Beispielnutzung:

my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'woof']
# index = [0, 3, 6]

# define excluded names list
excl_names_list = ['woof', 'c']

list_diff(my_list, excl_names_list)
>> ['a', 'b', 'd', 'e', 'f']
mirekphd
quelle