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

2024-04-18 06:14:01 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

上面的方法工作得很好,但是我试图在函数中包含“outputarray”变量,但是当我这样做时,递归步骤会将outputarray列表覆盖回空列表。你知道吗

我怎样才能在函数中指定一个列表,同时又能在递归过程中附加到它而不覆盖它呢?你知道吗


Tags: or函数in列表forifdeffloat
3条回答

您可以使用递归函数调用的返回值来扩展输出,而不是尝试插入全局变量:

def flattenarray(x):
    outputarray = []
    for elmt in x:
        if isinstance(elmt, float) or isinstance(elmt, int):
            outputarray.append(elmt)
        elif isinstance(elmt, list):
            outputarray.extend(flattenarray(elmt))
    return outputarray

这会创建比严格必要的更多的临时列表,因此效率不高。另一方面,它和原始代码一样容易阅读。你知道吗

另一方面,我建议对您的代码进行泛化。不必检查三种特定类型并跳过其他所有类型,只需检查元素是否可iterable:

全局变量:

def flattenarray(x):
    outputarray = []
    for elmt in x:
        try:
            outputarray.extend(flattenarray(elmt))
        except TypeError:
            # the error will be raised by the for loop in the recursive call
            outputarray.append(elmt)
    return outputarray

这与单线功能完美配合,基本思想与wim相同:

def flatten(lst, outputarray=[]):
    return sum( ([x] if not isinstance(x, (list,tuple))  else flatten(x)
                     for x in lst), outputarray)


lst=[1,2,3,[2,4,5,[6]],(7,8,9)]

print(flatten(lst))

结果:

[1, 2, 3, 2, 4, 5, 6, 7, 8, 9]

您需要从函数中创建输出数组。一种方法是在递归步骤中传递输出容器:

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

一个更具python风格的方法是让压扁器一个接一个地产生物品。请注意,isinstance可以接受类型的元组,因此只需调用它一次。你知道吗

def flatten(x):
    for elmt in x:
        if isinstance(elmt, (int, float, str, bytes)):
            yield elmt
        else:
            yield from flatten(elmt)

一个更正确的实现:

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)

相关问题 更多 >