好,那我們來對 list 多點認識,我們就從宣告 list 開始。 List 呢並不一定要從切字串 才能得到 list,你很多時候會自行製造 list,比如說咱們先來 declare 一個 empty list 的 做法就是寫一個變數名稱, 變成一個空的方括號,空的方括號 在這裡呢就是表示我是一個 list,裡面什麼東西都沒有, 這個時候如果你嘗試 print out 這個 list,就會看到這個東西,就什麼都沒有, 一對方括號裡面什麼都沒有,它的 length 就是 0,大家可以試一下。 那麼呢我們也可以在 declare 一個 list 的時候做一些這個各式各樣的這個 設定,比如說我想要三個 0 而不是空空的話,怎麼辦? 你呢,可以直接打,aList= 0,0,0,然後用括弧括起來, 那這個看起來就很 make sense,就是一個 list 裡面有三個 0 嘛,但有的時候你不想要這樣打,如果你要三百個 0 怎麼辦? 所以呢你也可以打一個 0,然後就把它延伸三次,就把它乘以 3,那麼呢就像字串一樣, 字串的乘法,或者是 list 的乘法,基本上就是延伸若干 倍,那麼你就會看到有三個 0,然後長度為 3。 那麼呢,我們也可以 declare 一個 list,讓它裡面裝著各式各樣不同的東西, 比如說像這裡,第一個值是一個整數,第二個值是一個字串, 第三個值是一個 boolean variable,應該說 boolean value,這些事情呢都是可以做的,一個 list 裡面可以裝著各式各樣的東西。 那麼我們來把 item 裝進 list 試試看, 我們呢如果要裝一個 item 到 list 的最後面,我們 可以使用 append 這樣一個函數,所以我們來稍微看一下這裡, 我們呢先用 input 讀入了一串字串, 然後把它切完了以後,現在 grades 裡面有東西啦, 我去後面 append(-1) 的話,會發生 什麼事情呢?就會發現我這個東西不但有五個 而且還有第六個,第六個是我們剛剛裝進來的,就是 -1,這樣子,那這裡呢也請大家注意一下 我們呼叫這個 append 的方式,就跟剛剛用字串呼叫 split 一樣, 是用一個東西,也就是字串,對不起,也就是 list 去 append 一個東西,所以 aList.append 就是 aList 會加東西,bList.append 就是 bList 會加東西,我們這個呼叫函數是有一個主詞存在的,就是誰去呼叫,誰就會加東西, 是這個樣子。 那麼,請注意,這裡我們 append 的東西 -1 是一個數字,所以 這個 -1 就是一個數字,你可以看到它印出來的時候也顯示出,它的確是一個數字。 那麼甚至呢,我們其實還可以在 list 裡面放 list,很快看一下這個例子, 我們呢,在 grades 裡面 append 的東西是另一個 list 叫做 [9,7,5] 結果我們在把它 print out 出來的時候就會有三個字串 和一個 list,這樣子,如果你這個時候呢去對它多做一點 存取或者是嘗試的話,你就可以發現,這看起來很像一個所謂的二維 維度為 2 的 list,那我們試一下。 好,今天這裡呢,我們先跑跑看,那麼我們先按照它的 建議輸入,1 2 3,就變成了我們畫面上看到的這個樣子,這個大概沒有什麼問題。 好,接下來我們想要多看一點東西,比如說,如果我嘗試要 print grades 的 length,像這樣, 請問,它會是 4 還是會是 6 呢?有點好奇,所以我們來試試看, 1 2 3,答案是 4,第一個東西,第二個東西,第三個 東西,第四個東西,對 grades 來說,它只有四個東西, 只不過是第四個東西長得比較複雜而已,這樣子。 那麼再來,我們今天呢,當然可以把任意一個東西取出來, 所以我這裡方括號 3,0,1,2,3,所以方括號 3 對應到的就是 [9,7,5] 那一個 list,所以我這裡印出來的東西,自己本身也是一個 list, 所以我能不能只把 7 拿出來呢?當然可以,我只要在這裡再方括號一次 就好了,這是什麼概念?前面我現在反白起來的東西,本身是一個 list, 那這個 list 的第 0 個東西的第 1 個東西,當然就可以取出來, 所以比如說像我現在這樣,那麼 [9,7,5] 的 7 就會被印出來,因為我們知道,它就是這個 list 裡面方括弧 1 會回傳的東西 所以按照這個邏輯呀,我們事實上可以比如說,咱們來把它們加起來吧,像這樣 這樣子呢第五行在做的事情就是去把 grades 的第 3 個,方括號 3 的那一個 item 也就是所謂的另一個 list 的三個數字加起來,大家可以看到就是 21 對吧?9 加 7 加 5 就是 21,所以 list 裡面是可以裝 list 的,如果你要 存取 list 裡面的 list 的某一個東西,你就是方括號一次,再方括號一次, 那其實所有的東西都很清楚,你不會拿錯東西的。 好,那麼呢我們今天有了 list, 經常我們就會把它拿來放在 loop 裡面,讓你的這個 loop counter 去跑一遍 那我們其實已經看過這個例子了,我們先看一下左邊這個。 我們呢可以用 range 來產出一個 讓這個 for 迴圈裡面可以跑的那樣的東西, 所以像這個東西呀,range 1,2,3,...,一直到 100,我們的 for 迴圈的 i 呢它就會,第一圈是 1,第二圈是 2,第三圈是 3,然後這個全部都加起來, 那麼最後我們 print sum 的時候 5050,就是這個答案。 好,那這個舊的沒什麼,我們來看一下 新的,新的這個程式碼是做這件事情,我們先 input,然後先切, 切完了以後印出來,就 1,2,3,4,5 嘛,都是字串,也就是五個子字串在這裡面。 然後呢我們開另外一個 grades 的清單, 這個是空的哦,然後接著我們用一個 for 迴圈來跑,跑什麼呢? 我們來把 grades list 裡面的東西 一個一個取出來,每取出一個,就把它轉成整數,然後 append 到 grades 裡面去, 也就是說呢,這個單引號 1 會變成數字 1,字串 2 會變成數字 2, 以此類推,每一圈我去把 grades list 裡面的一個字串拿出來,轉成整數 丟進 grades,那就是為什麼結果我們去 print grades 的時候,就會看到它們都是整數。 OK,所以大家有興趣試一下這個 program 你就會看到我們這裡顯示的結果。 好,那麼我們當然也可以在做這件事情的時候 順便做一些運算,所以這裡的前三行跟剛剛一樣, 但是呢我現在不僅僅是想要把它們變成整數,我還想要把它們乘以 2 的話,怎麼做?那這個有很多做法,那我們這裡稍微展示一下另一種做法。 就是我們剛剛呢是把 gradeStr 這裡面的 東西一個一個地拿出來,對不起,把 grades 一個一個拿出來, 但現在呢,我們也是有 grades ,對吧,我這裡的東西塞進去,所以我的 grades 裡面已經有五個字串了。 但現在我要做的事情是我去看 grades 有多長,然後呢 我的 i 一次一次地把 grades 裡面的某個東西 我用 i 去存取,用 i 去存取,取出來了以後呢把那個東西 轉成整數,順便乘以 2,然後呢把它拿來修改我的 grades 的內容,那麼結果出來的時候呢,就會長成 [2,4,6,8,10] 這個樣子。 好,很快地看一下, 我們今天在這裡呢,for i 的這個迴圈,i 依序會是 0 是 1,是 2,是 3,是 4,每一次呢它會去 grades 裡面把相對應的那個東西 取出來,然後轉成 int ,然後乘以 2,然後來覆蓋掉原本的東西, 原本的東西是一個字串,原本是 1,2,3,4,5,是字串,被這樣運算 完了以後就會變成那個數字乘以 2,而不再是一個字串了, 大概是這個樣子,好,試一下。 好,你可以看到,原本是字串 1,2,3,4,5, 但是轉換后變成數字 2,4,6,8,10 了。 讓我們來看兩個例子,來看看有了list我們可以做些什麽事情。 比如説啊,今天呢,我想要讓使用者,他可以輸入 一個月的數字,12,或8,或4,或什麽的。 然後它就告訴我,那個月的英文是怎麽寫的。 然後我想要 看縮寫。 所以我們的寫法是這個樣子。 我呢,先產生一個list, 這個list有十二個item,分別是字串"Jan",字串"Feb",依此類推。 就是十二個月的月份的縮寫。 有了這個以後,我請使用者輸入一個n。 那麽呢,我就把這個n拿來用在months這個裏面來查表。 如果n是3,那我們這裏就輸入month 2。 那month 2是0,1,2嘛,它就會告訴我Mar,那就是三月, 是這麽樣的一個意思,ok。 所以呢,這個例子我們想要强調的重點就是説, 你有了像清單這樣子的東西,像list這樣子的東西了以后,那麽你就可以很輕易地做到 這個給定輸入,我們就印出相對應的東西的這件事情。 如果我們今天沒有list, 而是使用這個完全土法煉鋼的方式的話,那你得要怎麽做呢?你就要變成 哦,他inputn了以後,if n == 1就print out 什麽什麽, else if == 2,print out 什麽什麽什麽,你的程式碼呢馬上就會變成有這個二三十行長, 就比這個醜多了,當然也比較不好維護。 所以這個用list的確是一個比較好的做法。 下一個例子呢,是假設我們今天想要寫一個這個井字游戲,就是tic-tac-toe。 井字游戲大家都玩過,比如說像右手邊的這個井字游戲,這個狀態是這個 打叉叉的這個玩家贏了。 好,那總之 我們今天如果想要寫一個這個井字游戲,那我們大概需要什麽呢? 我們需要有一個這個list。 它可能要是二維的,三乘三的,這樣講起來比較自然。 三乘三的list,然後我們用每一個list的element 去存0、 或1、 或true、 或false、 或什麽的, 來記錄這個人下在哪裏、 那個人下在哪裏。 那等到他們都下完了以後呢,我們可能就寫幾個if, else 之類的去判斷有沒有人獲勝。 比如説像這樣, 我這裏呢,有一個叫做game的list。 這個two dimensional 的 list 呢,裏面裝了是這樣子的東西,大家看一下。 它的意思就是説,game的第一個element是1,0,1。 第二個element是1,1,0,以此類推。 所以game本身有三個element。 而game的第一個element又是一個字串,裏面又是,對不起,又是一個list,- 又是1,0,1, 這樣子。 所以,1,0,1,1,1,0, 0,0,1,看得出來呢,就是0表示圈,1表示叉。 這個樣子。 好,所以呢,我透過maintain game這一個二維的list 我們就可以做什麽呢?就可以寫比如説這樣的一個for迴圈, 來判斷有沒有哪一個玩家,他呢是用橫列的方式來 獲勝。 那我們來看一下。 今天啊, 我有一個i,i的值呢可能是0、 可能是1、 可能是2。 那麽在i 是0的時候,我們在幹嘛?我們在看game[0][0]有沒有等於game[0][1]。 game[0][0]是這個數字,game[0][1]是這個數字。 又game[0][1]有沒有等於game[0][2]? game[0][2]在這裏。 如果我這些條件都成立的話,那麽我們就知道有一個玩家 他這一列都是他的,那他就贏啦。 那我們在這裏就print out那一個 相對應的value。 那我們就説他是玩家一,就獲勝,這樣。 那當然你不會只檢查一列,所以你會有,比如説,這裏會有三列嘛。 這就是爲什麽你的i 會跑0,然後跑1,然後跑2,以此類推。 那當然如果你發現有人贏了的話,也不用繼續檢查了,所以你就會break,大概是這- 個意思。 所以我們試一下。 好,比如説這個,這個一跑下去,什麽都沒有印出來,因爲沒有人贏嘛。 大家看剛剛這個圖,橫列的方式的時候呢, 是沒有人贏的。 所以我們換一個,把它改掉好了。 比如説這個, 我把這個改成1 的話,那麽這個program就應該要發現這件事情。 哎,果然,它就說啦,winner是一號,因爲有一列是滿足這個條件的。 好,那這個就是一個很簡單的二維list的應用。