将变量指定为列表而不在函数中覆盖它

Rl1*_*Rl1 2 python recursion list

我创建了一个函数,可以将嵌套列表展平为普通列表。

outputarray = []

def flattenarray(x):
    for elmt in x:
        if isinstance(elmt, float) or isinstance(elmt, int):
            outputarray.append(elmt)
        elif isinstance(elmt, list):
            flattenarray(elmt)
    return outputarray
Run Code Online (Sandbox Code Playgroud)

以上工作完美,但我试图在函数内部使用“outputarray”变量,但是当我这样做时,递归步骤会将 outputarray 列表覆盖回一个空列表。

我怎样才能使这项工作在函数内指定一个列表,同时能够在递归过程中附加到它而不覆盖它?

wim*_*wim 5

您将希望从函数内部创建输出数组。一种方法是在递归步骤中传递输出容器:

def flattenarray(x, outputarray=None):
    if outputarray is None:
        outputarray = []
    for elmt in x:
        if isinstance(elmt, float) or isinstance(elmt, int):
            outputarray.append(elmt)
        elif isinstance(elmt, list):
            flattenarray(elmt, outputarray=outputarray)
    return outputarray
Run Code Online (Sandbox Code Playgroud)

一种更 Pythonic 的方法是让 flattener 一个一个地产生项目。请注意,isinstance可以接受类型的元组,因此您只需调用一次。

def flatten(x):
    for elmt in x:
        if isinstance(elmt, (int, float, str, bytes)):
            yield elmt
        else:
            yield from flatten(elmt)
Run Code Online (Sandbox Code Playgroud)

更正确的鸭子类型实现:

def flatten(x):
    try:
        it = iter(x)
    except TypeError:
        yield x
        return
    if isinstance(x, (str, bytes)):
        yield x
        return
    for elem in it:
        yield from flatten(elem)
Run Code Online (Sandbox Code Playgroud)