Seite 1 von 1
Elemente aus einer Liste entfernen
Verfasst: Dienstag 13. Juli 2021, 17:06
von th.wieland
Hallo zusammen,
ich habe eine Liste, aus welcher ich bestimmte Elemente entfernen will.
Dazu hab ich einiges probiert, was nicht funktioniert.
Das hier funktioniert:
Code: Alles auswählen
liste0 = ['3ac','dfg','hjk','5tg','8qs','cv','cvb','2cv','r4','4wd','df','lfx']
liste1 = []
for i in liste0:
if re.match('^\d',i):
liste1.append(i)
liste1
['3ac', '5tg', '8qs', '2cv', '4wd']
Gibt es dafür einen eleganteren, pythonischeren Weg ?
Was mich an der Lösung stört ist, dass ich eine weitere Liste erzeugen muss.
Ich würde die nicht passenden Elemente gerne aus der Ursprungsliste löschen.
Hab ich mit
del und
for i in range(len(l)) probiert, aber durch das Löschen wird die Liste kürzer
und irgendwann gibt's n Index Error
vielen Dank
Tom
Re: Elemente aus einer Liste entfernen
Verfasst: Dienstag 13. Juli 2021, 17:15
von __deets__
Und genau weil durch das loeschen die Liste kuerzer wird, macht man das eben nicht, dass man eine Liste (oder jede Datenstruktur) manipuliert, statt eine neue zu erzeugen. Das ist also schon richtig so. Du kannst das natuerlich kompakter gestalten durch eine list-comprehension, und durch bessere Namen.
Code: Alles auswählen
all_things = ['3ac','dfg','hjk','5tg','8qs','cv','cvb','2cv','r4','4wd','df','lfx']
things_that_start_with_a_number = [item for item in all_things if len(item) and item[0].isdigit()]
print(things_that_start_with_a_number)
Re: Elemente aus einer Liste entfernen
Verfasst: Dienstag 13. Juli 2021, 17:18
von __blackjack__
@th.wieland: Der pythonische Weg *ist* es eine neue Liste zu erstellen. Das kann man mit einer „list comprehension“ etwas kompakter schreiben. Oder mit `re.compile()`, `filter()`, und `list()` arbeiten:
Code: Alles auswählen
In [213]: items
Out[213]:
['3ac',
'dfg',
'hjk',
'5tg',
'8qs',
'cv',
'cvb',
'2cv',
'r4',
'4wd',
'df',
'lfx']
In [214]: [item for item in items if re.match("\d", item)]
Out[214]: ['3ac', '5tg', '8qs', '2cv', '4wd']
In [215]: list(filter(re.compile("\d").match, items))
Out[215]: ['3ac', '5tg', '8qs', '2cv', '4wd']
Den "^" braucht man bei der `match()`-Methode nicht, der ist da implizit schon enthalten.
Re: Elemente aus einer Liste entfernen
Verfasst: Dienstag 13. Juli 2021, 22:47
von Nufnus
Mein Gedanke war jetzt eigentlich, dass er einfach nicht über den index iterieren darf, sondern so (wie in dem nicht auskommentiertem Code):
Code: Alles auswählen
def main():
names = ["Karla", "Max", "Rudolf", "Lisa"]
for name in names:
if name == "Max":
names.remove(name)
print(name + " gelöscht")
print(names)
# def main():
# names = ["Karla", "Max", "Rudolf", "Lisa"]
# for i in range(0, len(names)):
# if names[i] == "Max":
# names.remove(names[i])
# print(names[i] + " gelöscht")
# print(names)
if __name__ == "__main__":
main()
Ist das echt schlechter Stil?
Sicher müsste es doch sein, oder? Funktioniert bei mir recht zuverlässig.
Für jede Änderung an einer Datenstruktur immer gleich eine neue Datenstruktur erstellen zu müssen, stelle ich mir Performancetechnisch auch irgendwie nicht so toll vor?
Re: Elemente aus einer Liste entfernen
Verfasst: Dienstag 13. Juli 2021, 23:26
von LukeNukem
__blackjack__ hat geschrieben: Dienstag 13. Juli 2021, 17:18
@th.wieland: Der pythonische Weg *ist* es eine neue Liste zu erstellen. Das kann man mit einer „list comprehension“ etwas kompakter schreiben. Oder mit `re.compile()`, `filter()`, und `list()` arbeiten:
Naja, Regular Expressions sind zwar sehr bequem und angenehm, aber leider nicht besonders performant, und in diesem Fall auch überflüssig:
Code: Alles auswählen
In [13]: %timeit [item for item in items if re.match('\d', item)]
6.32 µs ± 54.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [14]: %timeit list(filter(re.compile("\d").match, items))
2.39 µs ± 50.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [15]: %timeit list(filter(lambda item: item[0].isdigit(), items))
1.41 µs ± 80.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [16]: %timeit [item for item in items if item[0].isdigit()]
799 ns ± 3.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Klar, bei so Kleckerkram macht das wenig, aber...

Re: Elemente aus einer Liste entfernen
Verfasst: Mittwoch 14. Juli 2021, 00:17
von __blackjack__
@LukeNukem: Bei den `isdigit()`-Varianten fehlt noch der Test ob `item` überhaupt etwas enthält den __deets__ in seinem Beispiel drin hat.
@Nufnus: Das funktioniert halt nicht wirklich *und* ist unperformant, weil bei jedes `remove()` die Liste wieder von vorne durchgeht und das Argument sucht, obwohl man den Index davon ja eigentlich schon kennt, und löschen bedeutet alle Elemente danach eine Position nach vorne zu kopieren. Was das nicht funktionieren angeht: Steck mal zweimal "Max" hintereinander in die Ausgangsliste und schau Dir das Ergebnis an.
Re: Elemente aus einer Liste entfernen
Verfasst: Mittwoch 14. Juli 2021, 08:40
von th.wieland
Hallo zusammen,
vielen Dank für die Tipps und die interessante Diskussion.
Das hat mich wieder ein gutes Stück weitergebracht.
Die for-Schleife durch List-comprehension zu ersetzen finde ich sehr elegant.
Damit bin ich noch nicht so vertraut. - Werd ich künftig vermehrt einsetzen.
Das Beispiel war etwas abstrahiert - die List-Elemente könnten auch andere Inhalte haben,
deshalb hab ich die Regex gewählt.
War mir auch nicht klar, dass die so auf die Performance gehen.
cu Tom
Re: Elemente aus einer Liste entfernen
Verfasst: Mittwoch 14. Juli 2021, 11:36
von Nufnus
__blackjack__ hat geschrieben: Mittwoch 14. Juli 2021, 00:17
@Nufnus: Was das nicht funktionieren angeht: Steck mal zweimal "Max" hintereinander in die Ausgangsliste und schau Dir das Ergebnis an.
Wow, das hätte ich jetzt nicht erwartet.
Vielen Dank auch von mir
