Die Challenge

Ich möchte eine neue Liste aus bereits existierenden Daten generieren. Dabei sollen einerseits komplexe Berechnungen auf den Daten passieren, andererseits möchte ich das Ergebnis noch filtern.
Beachte: Mit komplexen Berechnungen meine ich Berechnungen, die nicht im Rahmen einer List Comprehension leicht möglich sind.

Ohne List Comprehensions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def compute(element):
    ...
def condition(computed) -> bool:
    ...
old_data = ...
new_data = []

for element in old_data:
    computed = compute(element)
    if condition(computed):
        new_data.append(computed)

Das geht natürlich, aber das können wir besser.

Mit List comprehension - Teil 1

Eine simple List Comprehension.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def compute(element):
    ...
def condition(computed) -> bool:
    ...
old_data = ...

new_data = [
    compute(element)
    for element in old_data
    if condition(compute(element))
]

Nur eine Zeile mehr benötigt! Das muss ein Gewinn sein.
Der tatsächliche Gewinn ist in der Laufzeit. Jede .append() Option benötigt einige Zeit; eine List Comprehension wird im kompilierten Teil von Python ausgeführt. Tatsächlich ist dieser Code also relevant schneller.

Mein Problem an diesem Code ist, dass compute(element) doppelt aufgerufen wird. Was nicht cool ist, wenn die Funktion viel Zeit zum Berechnen benötigt.

Mit List Comprehension - Teil 2

Hier kommt der Walrus Operator ins Spiel, weil dadurch können wir das folgende machen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def compute(element):
    ...
def condition(computed) -> bool:
    ...
old_data = ...

new_data = [
    computed
    for element in old_data
    if condition(computed := compute(element))
]

Cool, oder?
Als schlechter Nebeneffekt: Es wird ein Stück komplexer, den Code zu lesen. Also nicht vergessen: Kommentare und Dokumentation!

Anwendung in der realen Welt

Mit ein paar Tests auf meinen alten Daten kann ich feststellen: Ich hatte den alten Ansatz, die Daten zu kopieren und dann herauszulöschen was ich nicht benötige. Mit diesem neuen Ansatz bin ich etwa um den Faktor 15 schneller geworden!