2016-09-30 3 views
1

Я строю функцию python, которая возвращает массив, который будет использоваться в поле выпадающего списка. Я пробовал две версии до сих пор.Прокрутка по категориям рекурсивно

Оба они работают с первым возвратом правильно отформатированного поля выбора. Однако первое решение идет только на два уровня. Я намерен добавить дополнительную глубину в категории.

Мой второй пример - моя попытка сделать это рекурсивно для поддержки большего количества уровней. Он работает, но мне интересно, как я могу его оптимизировать и добавить тире, похожие на первый пример.

# 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

Вам нужны пробелы после идентификатора? Или ваш смысл - каждый слой имеет одинаковую длину? –

+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 в другой метод, как это и избежать внутреннего loop метода в build_choice_tree2. Я также сделаю 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, и это добавит тире после ид, но это не будет добавлять пробелы, как ваш пример 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. –

Смежные вопросы