遞迴

在這裡,我們要舉一個稍微複雜的例子,目的是除了講解函式之外,還帶給讀者們一些其他的重要觀念。

還記得我們講過的巢狀結構嗎:

lst = [1, 2, [3, 4, 5], 6, [7, [8, 9]]]

假設我今天想要把裡面的每個元素 (不管這個元素在第幾層了) 都列印出來,該怎麼做呢?我們先試試看這樣:

for item in lst:
    print(item)

會得到這樣的結果:

1
2
[3, 4, 5]
6
[7, [8, 9]]

顯然不是我們想要的,當我們發現元素是清單的時候,應該要再次迭代該清單的項目:

for item in lst:
    if isinstance(item, list):
        for item2 in item:
            print(item2)
    else:
        print(item)

isinstance 是一個內建函數,可以幫助我們判斷變數的型態,他需要兩個參數,第一個是要測試的資料,第二個是指名要確認的形態,isinstance(data, type) 的意思就是問 datatype 型態的嗎?isinstance(item, list)就是問 itemlist 型態的嗎?

這樣我們可以在元素為清單時,再次迭代,元素不是清單時就直接印出,乍看之下這解決了問題,但是我們卻發現,如果清單位於第二層裡就沒辦法在迭代到了,好了,讀者們會說,那就再度迭代即可,但其實沒有那麼容易,我們並不知道要處理的清單究竟有多少層?

這時候我們只能使用 遞迴 的手法,但首要的工作,我們需要自定義一個函式:

def print_list(lst):
    for item in lst:
        if isinstance(item, list):
            print_list(item)
        else:
            print(item)

這個函式是這樣的,我們先迭代一次傳進來的清單,若發現某元素是清單,我們便去呼叫自己本身,否則我們直接把元素印出來。

我們會發現,不管清單位於哪一層,只要我們發現他,我們便呼叫 print_list 處理,就好像剝洋蔥一樣,一層一層剝開,我們不需要煩惱要剝幾層,只要知道,若沒有剝到最底的一層,我們便要繼續剝。這就是遞迴的手法,這在程式的世界是很重要的技巧,寫在這裡供讀者體會。

results matching ""

    No results matching ""