返回函数后将列表清空

时间:2018-11-24 20:29:09

标签: python list recursion

我正在开发的程序遇到一个麻烦。我需要制作一个函数,将一个列表(该列表中的项目可以再次包含列表)压平为一个简单列表。函数将列表作为参数获取,我需要使用递归返回新的展平列表,而不更改主列表。

这是我目前的尝试

 result = []

def flatten(nested_list):
    for i in nested_list:
        if type(i) != list:
            result.append(i)
        else:
            flatten(i)
    return result

这里的问题是,我想再次运行此函数时,它会记住最后一个结果,这意味着它将所有内容附加到末尾。但是我想做出一个新结果,仅包含当前嵌套结果的简单列表。再次调用函数时如何删除最后的结果?

谢谢。

3 个答案:

答案 0 :(得分:1)

这里的问题是您始终使用全局变量。使用可变全局范围通常是一种反模式。保持您的代码基本相同。一种简单的方法是使用累加器并将其作为参数传递给递归调用:

In [4]: def flatten(nested_list, result=None):
   ...:     if result is None:
   ...:         result = []
   ...:     for i in nested_list:
   ...:         if type(i) != list:
   ...:             result.append(i)
   ...:         else:
   ...:             flatten(i, result)
   ...:     return result
   ...:
   ...:

In [5]: x = [[1,[2], [3,4],5]]

In [6]: flatten(x)
Out[6]: [1, 2, 3, 4, 5]

In [7]: x
Out[7]: [[1, [2], [3, 4], 5]]

In [8]: flatten(x)
Out[8]: [1, 2, 3, 4, 5]

In [9]: x
Out[9]: [[1, [2], [3, 4], 5]]

不过,通常,您不想公开result作为参数来等待您开枪。因此,您可以定义一个“私有”辅助函数:

In [15]: def _flatten(nested_list, result):
    ...:     for i in nested_list:
    ...:         if type(i) != list:
    ...:             result.append(i)
    ...:         else:
    ...:             _flatten(i, result)
    ...:     return result
    ...:
    ...: def flatten(nested_list):
    ...:     return _flatten(nested_list, [])
    ...:
    ...:

In [16]: x = [[1,[2], [3,4],5]]

In [17]: flatten(x)
Out[17]: [1, 2, 3, 4, 5]

In [18]: x
Out[18]: [[1, [2], [3, 4], 5]]

In [19]: flatten(x)
Out[19]: [1, 2, 3, 4, 5]

或者,您可以在主函数中定义帮助程序,然后将结果变量放在闭包中

In [26]: def flatten(nested_list):
    ...:     result = []
    ...:     def _flatten(nested_list):
    ...:         for i in nested_list:
    ...:             if type(i) != list:
    ...:                 result.append(i)
    ...:             else:
    ...:                 _flatten(i)
    ...:
    ...:     _flatten(nested_list)
    ...:     return result
    ...:
    ...:

In [27]: flatten(x)
Out[27]: [1, 2, 3, 4, 5]

In [28]: x
Out[28]: [[1, [2], [3, 4], 5]]

In [29]: flatten(x)
Out[29]: [1, 2, 3, 4, 5]

答案 1 :(得分:0)

您遇到此问题的原因是因为result错误的scope。您需要将result声明放入函数中,以便在函数结束时超出范围且不再存在。

答案 2 :(得分:0)

您不需要全局变量,多余的参数,私有帮助函数或闭包-只需知道何时使用append()和何时使用extend()

def flatten(nested_list):
    result = []

    for i in nested_list:
        if isinstance(i, list):
            result.extend(flatten(i))
        else:
            result.append(i)

    return result

示例

>>> x = [[1, [2], [3, 4], 5]]
>>> flatten(x)
[1, 2, 3, 4, 5]
>>> x
[[1, [2], [3, 4], 5]]
>>> 

if type(i) != list:也许现在还不是类型检查的首选-isinstance()也可以用于子类。