2016-09-30 169 views
1

我正在构建一个python函数,该函数返回要在select下拉字段中使用的数组。到目前为止我已经尝试了两个版本。递归循环遍历类

他们都工作,第一次返回格式正确的选择字段。但是,第一种解决方案只能深入两层。我打算为这些类别增加更多的深度。

我的第二个例子是我试图递归地做到这一点,以支持更多的级别。它的工作原理,但我想知道如何优化它,并添加类似于第一个例子的破折号。

# 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

没有内部函数的第二个例子是完美的。我不知道默认列表,因为参数不会被重置。 – 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后加一个空格。 –