Python 递归函数中的默认列表值

Python 递归函数中的默认列表值,python,recursion,Python,Recursion,下面的函数每次运行时都会保留其列表中的值。由于使用了可变的默认参数,我最近作为Python了解了这个问题 我怎么修理它?在函数外部创建全局变量会导致相同的问题。将列表传递到函数中会中断递归,并且只显示第一级类别 def build_category_list(categories, depth=0, items=[]): '''Builds category data for parent select field''' for category in categories:

下面的函数每次运行时都会保留其列表中的值。由于使用了可变的默认参数,我最近作为Python了解了这个问题

我怎么修理它?在函数外部创建全局变量会导致相同的问题。将列表传递到函数中会中断递归,并且只显示第一级类别

def build_category_list(categories, depth=0, items=[]):
    '''Builds category data for parent select field'''
    for category in categories:
        items.append((category.id, '-' * depth + ' ' + category.name))
        if category.children:
            build_category_list(category.children, depth + 1)
    return items

通过传入列表或检查空值可以解决此问题。但您需要将列表向下传递到递归:

def build_category_list(categories, depth=0, items=None):
    if not items:
        items = []
    '''Builds category data for parent select field'''
    for category in categories:
        items.append((category.id, '-' * depth + ' ' + category.name))
        if category.children:
            build_category_list(category.children, depth + 1, items)
                                                              ^^^^^
    return items

或者,使用返回值构造答案-我的首选项请参见Antoine的答案…

传入列表或检查空值将解决此问题。但您需要将列表向下传递到递归:

def build_category_list(categories, depth=0, items=None):
    if not items:
        items = []
    '''Builds category data for parent select field'''
    for category in categories:
        items.append((category.id, '-' * depth + ' ' + category.name))
        if category.children:
            build_category_list(category.children, depth + 1, items)
                                                              ^^^^^
    return items

或者,使用返回值构造答案-我的首选项请参见Antoine的答案…

无需在递归函数中传递列表,只需将后续调用的结果连接到当前列表:

def build_category_list(categories, depth=0):
    '''Builds category data for parent select field'''
    items = []
    for category in categories:
        items.append((category.id, '-' * depth + ' ' + category.name))
        if category.children:
            items += build_category_list(category.children, depth + 1)
    return items

无需在递归函数中传递列表,只需将后续调用的结果连接到当前列表:

def build_category_list(categories, depth=0):
    '''Builds category data for parent select field'''
    items = []
    for category in categories:
        items.append((category.id, '-' * depth + ' ' + category.name))
        if category.children:
            items += build_category_list(category.children, depth + 1)
    return items

如何将列表传递到函数“中断递归”?只需将
items
设为非关键字参数,将
item
添加到递归调用中,并在调用函数时传递一个新列表,它应该可以工作。如何将列表传递到函数中“打破递归”?只需将
items
设为非关键字参数,将
item
添加到递归调用中,并在调用函数时传递一个新列表,它应该可以工作。