换行
else:
flatten_array(item)
到
else:
flattened_array+=flatten_array(item)
所以完整的功能看起来像
def flatten_array(array):
flattened_array = []
for item in array:
if not isinstance(item, list):
flattened_array.append(item)
else:
flattened_array+=flatten_array(item)
return flattened_array
这给了
flatten_array([1,2,[3]]) # [1,2,3]
flatten_array([1,2,[3,[4,5]]]) # [1,2,3,4,5]
flatten_array([1,2,[3,[4,5]],6,7,[8]]) # [1,2,3,4,5,6,7,8]
您的原始代码没有对递归调用做任何事情。您会在列表中取回结果,但只需将其丢弃。我们要做的是将它附加到现有列表的末尾。
此外,如果您不想继续创建临时数组,我们可以在第一次调用函数时创建一个数组,然后追加到它上面。†
def flatten_array(array,flattened_array=None):
if flattened_array is None:
flattened_array = []
for item in array:
if not isinstance(item,list):
flattened_array.append(item)
else:
flatten_array(item,flattened_array)
return flattened_array
这个版本的结果是一样的,也可以用同样的方式,但是在原来的版本中,每次调用函数都会创建一个新的空数组来处理。通常这不是问题,但根据深度或子数组的大小,这可能会在内存中累积。
此版本将数组扁平化为给定数组。当仅使用输入调用时(如flatten_array([1,2,[3]])),它会创建一个空数组来处理,否则它只会添加到给定数组(因此递归调用只需要给数组添加),就地修改它.
如果我们愿意,这具有允许您添加到现有数组的优势:
a = [1,2,3]
b = [2,3,[4]] # we want to add flatten this to the end of a
flatten_array(b,a) # we don't bother catching the return result here
print(a) # [1,2,3,2,3,4]
† 这里有一个微妙的地方。你可能会问为什么我们没有将函数定义为
def flatten_array(array,flattened_array=[]) 并去掉函数内部的测试。尝试并调用该函数几次。发生的情况是在函数定义时创建一次默认值,而不是每次调用函数时。这意味着在适当位置修改的默认数组由每个函数调用共享,从而导致它累积结果。
这可能不是我们想要的。通过将默认值设置为 None 并每次在函数内部创建一个新的空数组,我们确保对函数的每次调用都有一个唯一的空数组可供使用。