2016-09-30 7 views
1

Ich baue eine Python-Funktion, die ein Array zurückgibt, das in einem Auswahl-Dropdown-Feld verwendet werden soll. Ich habe bisher zwei Versionen ausprobiert.Kategorien rekursiv durchlaufen

Beide funktionieren, wobei die erste ein korrekt formatiertes Auswahlfeld zurückgibt. Die erste Lösung geht jedoch nur zwei Ebenen tief. Ich beabsichtige, den Kategorien mehr Tiefe zu geben.

Mein zweites Beispiel ist mein Versuch, dies rekursiv zu tun, um mehr Ebenen zu unterstützen. Es funktioniert, aber ich frage mich, wie ich es optimieren und Bindestriche ähnlich dem ersten Beispiel hinzufügen kann.

# first example two levels deep, formatted properly with dashes 
def build_choice_tree(): 
    categories = Category.query.get(1).children 
    items = [(1, 'None')] 
    for root in categories: 
     items.append((root.id, root.name)) 
     if root.children: 
      for subcat1 in root.children: 
       items.append((subcat1.id, '- ' + subcat1.name)) 
       if subcat1.children: 
        for subcat2 in subcat1.children: 
         items.append((subcat2.id, '--' + subcat2.name)) 
    return items 

# second example goes multiple levels, needs dashes 
def build_choice_tree2(): 
    categories = Category.query.get(1).children 
    items = [] 

    def loop(categories): 
     for category in categories: 
      items.append((category.id, category.name)) 
      if category.children: 
       loop(category.children) 
     return items 
    result = loop(categories) 
    return result 
+0

Benötigen Sie einige Leerzeichen nach der ID? Oder deine Bedeutung ist, dass jede Ebene die gleiche Länge hat? –

+0

Ich brauche einen Platz zwischen dem Strich und dem Namen – Casey

Antwort

2

einen Zähler verwenden die Anzahl der Striche zu speichern Sie möchten die Gedankenstriche um diese Anzahl addieren und multiplizieren. Um eine Funktion wirklich rekursiv zu machen, müssen Sie die return-Anweisung hinzufügen.

def build_choice_tree2(): 
    categories = Category.query.get(1).children 
    items = [] 
    count = 1 

    def loop(categories, count): 
     for category in categories: 
      items.append((category.id,'-' * count, category.name)) 
      if category.children: 
       count +=1 
       return loop(category.children, count) 
     return items 

    return loop(categories, count) 

Persönlich würde ich loop in eine andere Methode wie folgt trennen und die innere loop Methode in build_choice_tree2 zu vermeiden. Ich werde auch items ein Standardargument machen. Da Standardargumente (veränderbar) zur Funktionsdefinitionszeit ausgewertet werden, wird sie niemals auf ihren ursprünglichen Wert einer leeren Liste zurückgesetzt.

def loop(categories, count=1, items=[]): 
    for category in categories: 
     items.append((category.id,'-' * count, category.name)) 
     if category.children: 
      count +=1 
      return loop(category.children, count) 
    return items 
+0

Das zweite Beispiel ohne die innere Funktion ist perfekt. Ich kannte keine Standardliste, da das Argument nicht zurückgesetzt würde. – Casey

+0

Hier ist eine Liste von häufigen Python-Gotcha's, die Sie hilfreich finden können https://www.toptal.com/python/top-10-mistakes-that-python-programmers-make – danidee

1

ich ändern Sie Beispiel 2, und es wird Striche nach der ID hinzufügen, aber es wird nicht fügen Räume wie Ihr Beispiel 1.

# second example goes multiple levels, needs dashes 
def build_choice_tree2(): 
    # For the convenience of the test, I changed `categories` to a list. 
    categories = [{ 
     'id': 1, 
     'name': 'root', 
     'children': [{ 
      'id': 2, 
      'name': 'child1', 
      'children': [{ 
       'id': 3, 
       'name': 'child2', 
      }] 
     }] 
    }] 
    items = [] 
    def loop(categories, depth): 
     for category in categories: 
      items.append((category['id'], '-' * depth + ' ' + category['name'])) 
      if category.get('children'): 
       loop(category['children'], depth + 1) 
     return items 
    result = loop(categories, 0) 
    print(result) 
    return result 

if __name__ == '__main__': 
    build_choice_tree2() 
+0

Awesome danke yundong – Casey

+0

nein danke! Ich füge ein Leerzeichen nach der ID. –

Verwandte Themen