walk_tree: Ergebnisse einsammeln#

Gegeben:

  • eine beliebig tief verschachtelte Liste von (Listen von …) Zahlen

    • z.B. l = [ 1, [2, 3], [ [ [], 4,5],6]]

Aufgabe:

  • Sammle alle Zahlen in dieser Datenstruktur in einer Liste, die eine bestimmte Eigenschaft aufweisen

    • hier z.B. “ist eine gerade Zahl”

So eine Liste können wir so durchgehen:

def walk_tree(x): # dl ... durchsuche Liste
    
    if isinstance(x, list):
        for y in x:
            walk_tree(y)
    
    elif isinstance(x, int):
        
        if x%2 == 0: # Bsp. für positive Bedingung
            print(x)
            
    else:
        print(f"WARNUNG: ignoriere unbekanntes Element <{x}> vom Typ {type(x)=}")
l = [ 1, [2, 3], [ "Hallo", [ [], 4,5], {1: "one"}, 6]]
walk_tree(l)
2
WARNUNG: ignoriere unbekanntes Element <Hallo> vom Typ type(x)=<class 'str'>
4
WARNUNG: ignoriere unbekanntes Element <{1: 'one'}> vom Typ type(x)=<class 'dict'>
6

Frage: Wie können wir die Ergebnisse solch einer rekursiven Funktion in einer Liste einsammeln, statt sie nur auszudrucken?

Ergebnis in einer Datenstruktur aufsammeln#

Möglichkeit 1: Gib den Namen der Ergebnisliste als Parameter mit. Alle Aufrufe der Funktion walk_tree_2 erzeugen einen neuen Pointer auf immer dieselbe Ergebnis-Liste.

def walk_tree_2(x, Ergebnis): # dl ... durchsuche Liste
    
    if isinstance(x, list):
        for y in x:
            walk_tree_2(y, Ergebnis)
    
    elif isinstance(x, int):
        if x%2 == 0: # Bsp. für positive Bedingung
            #print(x)
            Ergebnis.append(x)
l = [ 1, [2, 3], [ [ [], 4,5],6]]

l_gerade_2 = []

walk_tree_2(l, l_gerade_2)
l_gerade_2
[2, 4, 6]

Ergebnis zurückgeben#

Möglichkeit 2: Erzeuge bei jedem neuen Aufruf von walk_tree_3() eine neue Liste. Diese wird dann mittels return zurückgegeben und von der aufrufenden Funktion mittels extend an die selbst gerade erzeugte eigene Ergebnisliste angehängt.

def walk_tree_3(x): # dl ... durchsuche Liste
    
    Ergebnis = []
    
    if isinstance(x, list):
        for y in x:
            Ergebnis.extend( walk_tree_3(y) ) # Wir erhalten eine Liste, also extend
    
    elif isinstance(x, int):
        if x%2 == 0: # Bsp. für positive Bedingung
            #print(x)
            Ergebnis.append( x ) # Wir fügen ein Element hinzu, also append
            
    else:
        print(f"WARNUNG: unbekannter Typ {type(x)=}")
        
    return Ergebnis # Wir geben eine Liste zurück
l = [1,2,4,5,6,7,8,9]
walk_tree_3(l)
[2, 4, 6, 8]
l_gerade_3 = walk_tree_3( l )
l_gerade_3
[2, 4, 6, 8]

Aufgabe: Erweitern Sie die Lösung so, dass sie auch mit Dicts funktioniert.