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

时间:2018-07-24 01:58:39

标签: python list recursion

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

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列表改写为空列表。

我该如何在函数内部指定一个列表,同时又能够在不递归的情况下将其追加到列表中?

3 个答案:

答案 0 :(得分:4)

您将要从函数内部创建输出数组。一种进行方式是在递归步骤中传递输出容器:

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)

答案 1 :(得分:1)

这与一个行函数完美配合,并且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]

答案 2 :(得分:0)

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

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

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

另外,我想建议对您的代码进行概括。您无需检查三种特定类型并跳过其他所有内容,而只需检查元素是否可迭代:

全局变量:

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