我正在开发的程序遇到一个麻烦。我需要制作一个函数,将一个列表(该列表中的项目可以再次包含列表)压平为一个简单列表。函数将列表作为参数获取,我需要使用递归返回新的展平列表,而不更改主列表。
这是我目前的尝试
result = []
def flatten(nested_list):
for i in nested_list:
if type(i) != list:
result.append(i)
else:
flatten(i)
return result
这里的问题是,我想再次运行此函数时,它会记住最后一个结果,这意味着它将所有内容附加到末尾。但是我想做出一个新结果,仅包含当前嵌套结果的简单列表。再次调用函数时如何删除最后的结果?
谢谢。
答案 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()
也可以用于子类。