<style> .new { color: red; font-weight: bold; } </style> # String 資訊之芽 熊育霆 2022/03/27 --- ## 在開始之前 ---- ### 肌肉記憶 Muscle Memory 等等中間會不時穿插一些練習時間 把每個範例在你的電腦上照著打一遍,善用你的肌肉記憶把 python 的語法記熟 (實作比抄筆記還要有用許多) --- ## Recall: what are strings? 我們來複習第一週教過的東西 ---- 一段文字 ```python= print(type("Hello, world!")) # <class 'str'> ``` ---- 可以用單引號或雙引號包起來 ```python= "bing chilling" # 用雙引號包起來 'bing chilling' # 用單引號包起來 ``` ---- 加法(串接)、乘法(重複接) ```python= name = "Madoka" print("Hello, " + name) # Hello, Madoka print(name * 3) # MadokaMadokaMadoka ``` ---- 跳脫字元,例如 `\n`, `\'` ```python= print('Hello. It\'s me.') # Hello. It's me. print('Never gonna give you up', 'Never gonna let you down', 'Never gonna run around and desert you', sep='\n') """Never gonna give you up Never gonna let you down Never gonna run around and desert you """ ``` ---- 多行字串 ```python= print("""這幾行 會被 印出來 :)""") ``` ---- f-string ```python= name = "Kira Yoshikage" age = 33 print("name=", name, "age=", age) print(f"name={name} age={age}") print(f"{name=} {age=}") ``` ---- Questions? ![](https://thumbs.gfycat.com/AllPersonalKingsnake-size_restricted.gif) --- ## 名詞解釋:字元 char 字元:一個字 ```python= 'a' 'b' 'c' ``` 字串:由一串字元組成 --- ## 補充:Python 沒有 char 在 C, C++, Java 等程式語言中有 char (字元) 資料型別,但在 Python 中沒有 char 資料型別,只有長度為 1 的字串。 ```c= char c = 'a'; // C/C++ ``` ```python= c = 'a' # Python # or c = "a" print(type(c)) ``` --- ## 跟 `list` 差不多一樣的地方 Bing Chilling! ---- ![](https://c.tenor.com/XVZlONPlQUIAAAAd/binchiling-john-cena.gif) ---- ### 加法和乘法運算 加法(串接)、乘法(重複接) ```python= name = "Madoka" print("Hello, " + name) # Hello, Madoka print(name * 3) # MadokaMadokaMadoka ``` 上週教了 `list` ,其實 `list` 也有對應的操作 ```python= print(['c'] + [8, 7] + [6, 3]) # ['c', 8, 7, 6, 3] print([8, 7] * 3) # [8, 7, 8, 7, 8, 7] ``` ---- ### 比較運算 兩字串是否相等 ```python= print("abc" == "abc") # True print("abc" != "abc") # False ``` 比較兩字串字典序 ```python= print("abc" < "abd") # True print("abc" < "abcd") # True print("abc" > "def") # False ``` 有點難很簡短的解釋什麼是字典序,大家可以看一下[這個](https://en.wikipedia.org/wiki/Alphabetical_order#Ordering_in_the_Latin_script),簡單來說就是從頭比到尾、都一樣比長度 ---- ### `in`, `not in` ```python= text = 'abc' print('a' in text) # True print('ab' in text) # True print('ac' in text) # False print('ac' not in text) # True ``` ---- ### `len` ```python= zhang_xina = "早上好中國" print(zhang_xina) print(len(zhang_xina)) # 5 ``` ---- ### 取第 i 個 ```python= zhang_xina = "早上好中國" print(zhang_xina[0]) # 早 print(zhang_xina[1]) # 上 print(zhang_xina[3]) # 中 print(zhang_xina[-1]) # 國 print(zhang_xina[5]) # IndexError: string index out of range ``` 可以試試 `zhang_xina = ["早", "上", "好", "中", "國"]` ---- ### Slicing ```python= zhang_xina = "早上好中國" print(zhang_xina[2:4]) # 好中 print(zhang_xina[:3]) # 早上好 print(zhang_xina[2:]) # 好中國 print(zhang_xina[::-1]) # 國中好上早 print(zhang_xina[:-3:-1]) # 國中 ``` 可以試試 `zhang_xina = ["早", "上", "好", "中", "國"]` ---- ### 可迭代 Iterable 如果你忘記什麼是 iterable,就是一句話:可以 for 它 ```python= zhang_xina = "早上好中國" for word in zhang_xina: print(word) """早 上 好 中 國 """ ``` ---- Questions? 早上好資訊之芽,現在我有 list,我很喜歡 list ... --- ## 小補充 iterable [還不錯的教學文件](https://www.pythonlikeyoumeanit.com/Module2_EssentialsOfPython/Iterables.html) 我們來看一下 definition 和一些花式用法 --- ## 跟 list 不一樣的地方 ---- ### Immutable 不能改值 ```python= text = "abcde" text[2] = 'f' # TypeError: 'str' object does not support item assignment ``` ---- 如果要改掉某個字的話只能很費工地這樣做 ```python= text = "abcde" new_text = text[:2] + "f" + text[3:] print(new_text) # abfde ``` ---- 為什麼要這樣設計呢?我也很好奇。於是我找到了[這篇問答](https://stackoverflow.com/questions/8680080/why-are-python-strings-immutable-best-practices-for-using-them),大家有興趣可以看看。不過你們需要知道更多才比較能體會這樣設計的好處。 簡單來說就是,恩,dict 和 hash 之類的?你下半堂課就會知道這些東西了 ---- 沒有 immutability 的話可能會發生一些怪事 ```python= a = [8, 7, 6, 3] b = a a[2] = 5 print(f"{a=}") # a=[8, 7, 5, 3] print(f"{b=}") # b=[8, 7, 5, 3] # Remark: use id print(f"{id(a)=}") print(f"{id(b)=}") ``` 回憶一下為何我們會看到 a, b 會同時被改值 這是因為他們 reference 到同一個物件 ---- [Why is immutability so important (or needed) in JavaScript?](https://stackoverflow.com/questions/34385243/why-is-immutability-so-important-or-needed-in-javascript) 雖然不是 Python 但是核心精神差不多,可以參考看看 ---- Questions? ---- 課間練習:輸入一行字,輸出第$i$行把第$i$個字元取代成`*`後印出,詳見範例 Input: ```txt abcdefg ``` Output: ```txt *bcdefg a*cdefg ab*defg abc*efg abcd*fg abcde*g abcdef* ``` --- ## String 的各種操作 (method) ---- String 的操作有[這麼多](https://www.w3schools.com/python/python_ref_string.asp),當然我只會講常用的那幾個 ---- 如果你想知道有沒有什麼偷吃步的方法達成你想要做的事情,就把這件事拿去餵狗 比如說你可以試著把以下這些東西拿去 google * Python turn string uppercase (把每個字元轉成大寫) * Python string first capital (把第一個字轉成大寫) * Python string remove blank (把空白拿掉) Google 不會笑你的英文,所以隨便打都沒差 --- ### replace ```python= lyrics = """Never gonna give you up Never gonna let you down Never gonna run around and desert you """ modified_lyrics = lyrics.replace("Never", "Always") print(modified_lyrics) print(lyrics) ``` ---- 就是搜尋與取代 注意:原本的字串不會被改動 更多可以參考[這裡整理的懶人包](https://www.w3schools.com/python/ref_string_replace.asp) ---- **所以...現在是練習時間** 1. 把前面範例中的 "gonna" 取代成 "wanna" 2. 把前面範例中的 "gonna" 取代成 "wanna",並且把 "you" 取代成 "me" --- ### isdigit & isalpha & isalnum 判斷字串中是否全為數字/字母/數字與字母 ---- ```python= print("119".isdigit()) # True print("Hello".isalpha()) # True print("Hello, it's me".isalpha()) # False print("C8763".isalnum()) # True ``` ---- 當然,我們可以不用 `isdigit` 暴力做到這些事情 ```python= s = "271828" flag = True for ch in s: if not "0" <= ch <= "9": # if ch not in "0123456789": flag = False print(flag) ``` 但這樣很累欸 ---- 當然還有很多其他的 is 家族,你們可以自己慢慢看,不用背 ---- Questions? ---- **所以...現在是練習時間** 搭配 `isdigit` 和 `len` 判斷一串數字是否為合法的手機號碼 1. 十個數字 2. 前兩位是 09 ```python= text = input() # 請開始你的練習 ``` --- ### strip ```python= new_text = " aaaaa ".strip() print(f"{new_text=}") # new_text='aaaaa' ``` 把字串頭尾的空白拿掉,並且回傳新的字串 ---- 沒錯,就這樣 你們可以想一下,你瀏覽的網站中哪些地方會用到這個功能 Questions? --- ### lower & upper 將字串中的英文字母全變成小寫或大寫 ```python= print("Ko no Dio da!".upper()) # KO NO DIO DA! print("Ko no Dio da!".lower()) # ko no dio da! ``` ---- 一些使用情境:不分大小寫搜尋某個字串,例如說 ```python= want_to_search = "Iso" text = "Isometry, isomorphism, isolated" text.lower().find(want_to_search.lower()) # 下一小節是 find ``` 這可以搭配後面的其他東西做練習 --- ### find 尋找 ```python= lyrics = """Never gonna give you up""" print(lyrics.find("gonna")) # 6 ``` ---- 用法 ```python= string.find(value, start, end) ``` * value: 欲尋找的東東 * start: 從哪裡開始找,預設是 0 * end: 找到哪裡結束,預設是到字串結尾 ---- 把所有 gonna 找到 ```python= lyrics = """Never gonna give you up Never gonna let you down Never gonna run around and desert you """ positions = [] start = 0 value = "gonna" while True: ret = lyrics.find(value, start) if ret == -1: break positions.append(ret) start = ret + len(value) print(positions) ``` ---- Questions? --- ### split 把字串切成一堆字串用 list 包起來 ```python= text = "Never gonna give you up" splitted = text.split() print(splitted) # ['Never', 'gonna', 'give', 'you', 'up'] ``` ---- 什麼時候會用到? 很多時候 ---- 範例:計算你輸入了幾個英文單字 ```python= words = input().split() print(len(words)) ``` ---- 範例:計算一堆數字的平均 ```python= numbers = list(map(float, input().split())) print(sum(numbers) / len(numbers)) ``` ---- 更詳細的用法 ```python= string.split(separator, maxsplit) ``` `separator`: 用什麼來切,預設是空白 `maxsplit`: 最多切幾個 可以參考 [w3school](https://www.w3schools.com/python/ref_string_split.asp) ,但我是沒用過那兩個參數幾次啦 ---- 人肉直譯器練習 猜猜看以下的東西會印出什麼,猜完之後在自己的電腦上跑跑看 ```python= a = "1 2 3 4 5".split() b = "1 2 3 4 5".split(' ') c = "1 2 3 4 5".split('3') print(f"{a=}\n{b=}\n{c=}") ``` `split()` 和 `split(' ')` 其實有一些微妙的差異,細節需要注意一下 ---- 比如說 這段程式碼 ```python d = list(map(int, "1 2 3 4 5".split(' '))) ``` 會噴錯 ```python ValueError Traceback (most recent call last) /tmp/ipykernel_409726/410874544.py in <module> ----> 1 d = list(map(int, "1 2 3 4 5".split(' '))) ValueError: invalid literal for int() with base 10: '' ``` 因為空字串不能被轉成 `int` ---- 下面這個就不會出事 ```python d = list(map(int, "1 2 3 4 5".split())) ``` ---- Questions? --- ### join 把一堆用 list 包起來的字串合成一個字串 ```python= words = ['Never', 'gonna', 'give', 'you', 'up'] print(' '.join(words)) # Never gonna give you up ``` 就是把 split 反過來 ---- 用法 ```python string.join(iterable) ``` 用 `string` 把 `iterable` 裡面的東西全部接起來 `iterable` 裡面必須是一些字串 ---- 人肉直譯器練習 有些是會噴錯的 要看答案的話複製到自己的電腦上跑跑看 ```python ''.join([1, 2, 3]) ``` ```python ''.join(['1', '2', '3']) ``` ```python ''.join(map(str, range(10))) ``` ```python ', '.join(map(str, range(10))) ``` ---- Questions? --- 這麼多誰背的完阿? 對阿很少人會特地去記這些東西,如果你想要達成什麼目的,就把你想做的事情拿去餵 google 看看 --- ## 綜合練習 有時間的話我應該現場寫一下 ---- 計算一個英文句子中有幾個字 例如 "Hello, it's me." 有三個, "Never gonna give you up" 有五個字 ---- 判斷一個字是否是回文 例如 "ada", "racecar" 是,"sprout" 不是 ---- 可以在 [LeetCode](https://leetcode.com/tag/string/) 找些簡單題來玩玩 ---- Questions? --- ## 作業 [3109](https://neoj.sprout.tw/problem/3109/) [3040](https://neoj.sprout.tw/problem/3040/) [3046](https://neoj.sprout.tw/problem/3046/) --- End --- ## 參考解答們 ---- ```python= text = input() for i in range(len(text)): print(text[:i] + '*' + text[i+1:]) ``` ---- ### replace ```python= new_lyrics = lyrics.replace("gonna", "wanna") ``` ```python= new_lyrics = lyrics.replace("gonna", "wanna").replace("you", "me") ``` ---- ### isdigit & isalpha & isalnum ```python= text = input() print(len(text) == 10 and text[:2] == "09" and text.isdigit()) ```
{"metaMigratedAt":"2023-06-16T21:13:17.690Z","metaMigratedFrom":"YAML","title":"String","breaks":true,"slideOptions":"{\"transition\":\"fade\"}","contributors":"[{\"id\":\"f93c8d2e-91fa-44cf-b9d2-ea6d875fcb79\",\"add\":10316,\"del\":676}]"}
    703 views