2016-07-13 11 views
2

ich eine verschachtelte dict haben, die wie folgt aussieht:Rekursion in dict

enter image description here

Es gibt mehrere Verschachtelungen innerhalb des Schlüssel children. Ich möchte den Schlüssel branch immer dann erfassen, wenn der Schlüssel children vorhanden ist. Da es mehrere children gibt, möchte ich dies für jedes Kind tun. Natürlich kann jedes Kind auch weitere children haben. Diese Verschachtelung kann bis zu 7 Ebenen umfassen.

Um dies zu erreichen, könnte ich entweder eine boneheaded 7-for-loop-Methode schreiben oder Rekursion verwenden. Also gab ich einen Schuss Rekursion und kam mit dem folgenden Code auf:

def GatherConcepts(header): 
    if 'children' in header.keys(): 
     if len(header['children']) > 0: 
      if 'branch' in header.keys(): 
       concepts.append(header['handle']) 
       if 'children' in header.keys(): 
        for j in range(0, len(header['children'])): 
         GatherConcepts(header['children'][j]) 
      else: 
       for i in range(0,len(header['children'])): 
        GatherConcepts(header['children'][i]) 

Das Problem mit diesem Code ist, dass es mir nur 2 Ebene gibt (weil ich die Funktion selbst 2 mal bin Aufruf, damit nicht Rekursion richtig), nicht 7.

Wie kann ich dies verbessern, um alle Ebenen zu bekommen?

Alle Zeiger würden sehr geschätzt werden.

+0

Können Sie ein Beispiel für die Eingabe (die bereitgestellte Eingabe) und die Ausgabe, die Sie davon erwarten würden, zeigen? –

+0

Es sieht so aus, als hätte das Top-Level-Dict 'children', aber keine' branch' (außer, dass ich diese Ausgabe falsch lese) ... – mgilson

+0

Außerdem wird FWIW, 'key in some_dict.keys()' weniger effizient sein (signifikant auf python2.x) als 'key in some_dict'. – mgilson

Antwort

1

Sie haben einige unnötige Redundanzen. Wenn ich Sie richtig verstehe, müssen Sie die Handles der Liste getrennt von der Rekursion hinzufügen, weil Sie branch im übergeordneten Test testen möchten.

def GatherConcepts(header): 
    if 'children' in header and 'branch' in header: 
     for child in header['children']: 
      concepts.append(child['handle']) 
      GatherConcepts(child) 

Sie brauchen nicht die Länge der header['children'] zu testen - wenn es Null ist, dann wird die Schleife einfach nichts tun.

+0

Ich will nicht den Griff des Zweiges, ich will den Griff des Kindes. Ich stimme zu, dass die zweite if-Anweisung unnötig ist. Ich habe das nur eingeschlossen, um mehr Zeug auszuprobieren. – Patthebug

+0

Dieser Code funktioniert in den meisten Fällen gut, aber es gibt mir den 'Branch's '' Handle', während ich den '' '' '' Handle'' wünsche. – Patthebug

+0

Ich nahm das vor 20 Minuten heraus, jetzt gibt es den Griff des Kindes. – Barmar

0

Um Rekursion korrekt zu erhalten, können Sie diese einfache Schablone für sie verwenden:

def recursive(variable): 
    if something: 
     # base step 
     return somethingelse 
    else: 
     # recursive step 
     return recursive(somethingelse) 

In Ihrem Fall können Sie so etwas wie dies versuchen:

def gather_concepts(header): 
    # recursive step 
    if 'branch' in header and 'handle' in header: 
     concepts.append(header['handle']) 
    if 'children' in header: 
     for child in header['children']: 
      return gather_concepts(child) 
    # base step 
    else: 
     return 

Sie diesen Code zwicken sollte aber unter deinen Bedürfnissen, weil ich es nicht selbst getestet habe.

+0

Wenn ich jetzt das Diktat genauer betrachte, denke ich, dass der 'branch's' handle' auch unnötig sein kann. Ich bin nur hinter dem 'handle' Feld in jedem' Kind'. Ich möchte nur eine endgültige Liste aller "Handle" in "Kinder". – Patthebug