2016-09-30 3 views
1

私は選択ドロップダウンフィールドで使用する配列を返すpython関数を構築しています。私はこれまでに2つのバージョンを試しました。再帰的にカテゴリをループする

両方とも機能し、最初は正しくフォーマットされた選択フィールドを返します。しかし、最初の解決策は2つのレベルにしか行きません。私は、カテゴリに深みを加えるつもりです。

私の2番目の例は、これを再帰的に実行してより多くのレベルをサポートしようとしています。それは動作しますが、私はそれをどのように最適化し、最初の例と同様のダッシュを追加することができますかと思います。

# 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

idの後ろにスペースが必要ですか?または、あなたの意味はそれぞれのレイヤーが同じ長さですか? –

+0

ダッシュと名前の間にスペースが必要 – Casey

答えて

2

のようにスペースを追加しませんあなたはダッシュをその数だけ追加して掛けたいと思っています。また、関数を本当に再帰的にするには、returnステートメントを追加する必要があります。

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) 

個人的に私はこのような異なる方法にloopを分離しbuild_choice_tree2内側loop方法を避けるだろう。私もitemsをデフォルトの引数にします。デフォルトの引数(変更可能)は関数定義時に評価されるので、空のリストの元の値にリセットされることはありません。

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

内部関数のない2番目の例は完璧です。引数がリセットされないので、私はデフォルトリストを知らなかった。 – Casey

+0

一般的なpython gotchaのリストは、役に立つhttps://www.toptal.com/python/top-10-mistakes-that-python-programmers-makeを参照してください。 – danidee

1

は、私はあなたの例2を変更し、ダッシュの数を格納するためのカウンタを使用し、それは、IDの後にダッシュを追加しますが、それはあなたの例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

yundongありがとうございました – Casey

+0

私はidの後ろにスペースを追加します。 –