更改線路
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
並每次在函數內創建一個新的空數組,我們確保每次調用該函數都有一個唯一的空數組來處理。
謝謝。不知道可以使用'+'運算符來追加到列表。 – Pyderman
@Pyderman它並不完全追加。它將兩個列表合併在一起。如果你想添加一個項目到列表中,你需要使用append方法,但是如果你有兩個列表,並且你想將其中一個添加到另一個列表的末尾,你可以添加它們。請注意,如果你已經學習了很多代數,這是一個非交換加法的例子。 – Matthew
@Matthew感謝您的補充闡述和替代解決方案。 – Pyderman