循环遍历类别

时间:2016-09-30 01:19:00

标签: python recursion

我正在构建一个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

2 个答案:

答案 0 :(得分: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作为默认参数。因为默认参数(mutable)是在函数定义时计算的,所以它永远不会重置为它的空列表的原始值。

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

答案 1 :(得分: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()