# 04 Immutable Data Types 前面介紹了 Accumulation 和 Function,這兩個都是程式裡負責做事情的工具,例如 - Built-in functions (`print()`/`type()`/`input()`) 讓我們體驗到 Python 的方便性、 - Built-in types (`int`/`string`/`range`) 讓我們認識 Python 組織語言的方式、 - Arithmetic Operators (`+`/`-`/`*`/`%`) 能有效利用數字、 - Boolean logic (`True`/`False`) 是貼近電腦判斷事物的根源、 - Loops (`for`/`while`) 可以重複執行指令、 - conditional statements (`if`/`else`/`elif`) 讓程式有判斷能力、 - Modules (`import ...`) 可以使用其他地方來的程式碼、 - Functions (`def ...()`) 讓程式可以被重複使用、 - Methods (`ooo.xxx`) 讓我們知道 type 都有些支援的 funcitons、 - Scope 一瞥程式的記憶體管理、 而 assignment operator (`=`) 是使用各種 type 的 variable 的起點 程式的運作建立在這些東西之上,也幾乎所有程式語言都有上述的東西們,剩下的就是讓事情更簡單的東西囉 接下來幾章我們來講一些 type 的細項吧\ 比之前簡單些囉 資工用語我們會說接下來的東西算是「資料結構」,也就是探討儲存和使用資料的各種形式與手段。 所謂資料(data) ,就是各式各樣的 variable,有些是可能是 string 也有些可能是 int 或各種 type,這些資料如果全部都放在個別的 variable 裡,不只浪費記憶體空間,取得方式還很有限(只能從叫 variable name 來拿到)。 這邊我們來進一步探討 string 和 tuple~<br/><br/> ## String 每一個 string 都有自己的長度\ 透過 len() 就可以得知\ 試試 ```python def main(): myString = "Hello World" print(len(myString)) main() ``` 得到 _11_<br/> 這邊可以發現空白鍵也算一格喔<br/><br/><br/> String 也可以相加,試試 ``` python def main(): myString = "Hello" + " World" print(myString + "!!!") main() ``` <br><br>接著來看一個寫程式很重要的概念 **index**\ 顧名思義,索引的意思\ 也就是電腦在讀資料時,幫它們編號的行為\ Index 用中括號`[]`表示,從零開始\ 試試 ```python def main(): myString = "Hello World" print(myString[0]) main() ``` <br>另外,index 也有負的,試試 ```python def main(): myString = "Hello World" print(myString[-1]) main() ``` <br><br> 表示第a個字元到第b個字元時,我們會用冒號來表示\ 試試下面兩個 ```python def main(): myString = "Hello World" print(myString[0: 4]) main() ``` ```python def main(): myString = "Hello World" print(myString[0: -2]) main() ``` 除此之外,加入第三個變數則表示間距(很少用)\ 試試 ```python def main(): myString = "Hello World" print(myString[0: -2: 2]) main() ``` 像前面介紹過的 method,String 本身就有內建很多功能了,\ [String methods](https://docs.python.org/3/library/stdtypes.html#string-methods) 除了介紹過的 `.islower()`、`.isnumeric()`等,也可以試試下面 ```python def main(): myString = "Hello World" print(myString.lower()) print(myString.upper()) print(myString.replace("l", "1")) main() ``` 雖然,通常,我個人會用的只有 `.replace()` -------- ## Mutable/Immutable 接下來講一個重要的資料觀念,程式語言中拿來存資料的type有很多種,\ 有些存了之後可以更改,有些則不行<br/><br/> 可以改的叫做 **Mutable**\ 不能改的叫做 **Immutable**<br/><br/> **String** 就是有名的 immutable 例子<br/><br/> 試試以下 ```python def main(): myString = "Hello World" myString[0] = "J" main() ``` 我們得到 _Error_<br/><br/> 乍看之下,程式碼想要將myString的第一個字母改成J,\ 但這是行不通的,因為一旦宣告,所有string都**不能**再更動<br/><br/> 這時候,如果想要得到上面程式碼的效果,就必須使用下面方式 ```python def main(): myString = "Hello World" myString2 = "J" + myString[1:] print(myString2) main() ``` `myString` 是原本的 string\ `myString2` 是新的 string\ 既然 string 是可以被 `+` 起來的,\ 那麼可以直接將新的字首加上原本的字母們,就可以達到期望的效果嘍<br/><br/><br/> 之前已經學過if 和 for loop 還有 function,\ 下面例子將三者結合,提供了string的新玩法 ```python def removeVowels(mystr): vowels = "aeiou" vowels += vowels.upper() mystr_noVowels = "" for i in range(len(mystr)): if mystr[i] not in vowels: mystr_noVowels += c return mystr_noVowels def main(): print(removeVowels("Mississippi")) main() ``` 其實要 loop through 一個 string 不需要像上面一樣麻煩,可以改寫成下面 至於要用哪一種,就看狀況囉 ```python def removeVowels(mystr): vowels = "aeiou" vowels += vowels.upper() mystr_noVowels = "" for c in mystr: if c not in vowels: mystr_noVowels += c return mystr_noVowels def main(): print(removeVowels("Mississippi")) main() ``` ------- ## Tuple 接著,介紹另一個資料型態,**tuple**\ Tuple 是另一個 immutable type\ 以數個值在括號內,以逗號區隔組成<br/><br/> 其實我們在一個Function return時,直接用逗號return兩個值的行為,就是在製造tuple\ 試試 ```python def foo(): x = 5 y = "a" return x, y print(foo()) ``` \ _(5, 'a')_<br/><br/> Tuple 不限內容物的 type,可以 tuple 裝在 tuple 裡,\ 也可以進行乘法\ 試試 ```python def main(): num = (5) * 4 num1 = (5,) * 4 print(num) print(num1) main() ``` \ _20_\ _(5, 5, 5, 5)_<br/><br/> 由此可知,tuple 的特性 <br><br> -- :::spoiler `Additional Readings` chapter 9 strings https://runestone.academy/ns/books/published/thinkcspy/Strings/toctree.html Tuples and Mutability https://runestone.academy/ns/books/published/thinkcspy/Lists/TuplesandMutability.html ::: <br></br> :::info [BACK](https://hackmd.io/@lhsueh1/python101) :::