## List Comprehension Be Pythonic! --- Pythonic? ---- ### 翻轉 list :x: ```python= A = [1,2,3,4,5] B = [] for i in range(len(A)-1, 0 ,-1): B.append(A[i]) ``` :heavy_check_mark: ```python= A = [1,2,3,4,5] B = A[::-1] ``` ---- ### 印出 1~100 的偶數 :x: ```python= for i in range(1,101): if i % 2 == 0: print(i) ``` :heavy_check_mark: ```python= print(list(range(1,101))[1::2]) ``` ---- ### 印出 1~100 被 2 整除但不被 5 整除的數 :x: ```python= for i in range(101): if i % 2 == 0 and i % 5 != 0: print(i) ``` :heavy_check_mark: ```python= print([i for i in range(1, 101) if i % 2 == 0 and i % 5 != 0]) ``` ---- # wtf?? --- ## List Comprehension 簡單三步驟 ---- ![](https://i.imgur.com/Qm6bJtY.gif) 1. 源頭 2. 輸出 3. 修飾條件(optional) ---- ### 印出 1~100 被 2 整除但不被 5 整除的數 1. 源頭:`1~100` 2. 輸出:`i` 3. 修飾條件:`i % 2 == 0 and i % 5 != 0` ```python= print([i for i in range(1, 101) if i % 2 == 0 and i % 5 != 0]) ``` ---- ```flow st=>start: i: 1~100 op=>operation: i % 2 == 0 and i % 5 != 0 op2=>operation: i st->op->op2 ``` --- ## 練習 ---- ### 1-50所有5的倍數 :heavy_check_mark: <span> ```python= [i for i in range(1,51) if i % 5 == 0] ``` <!-- .element: class="fragment" data-fragment-index="1" --></span> ---- ### 1-100所有3的倍數但不是9的倍數 :heavy_check_mark: <span> ```python= [i for i in range(1,101) if i % 3 == 0 and i % 9 != 0] ``` <!-- .element: class="fragment" data-fragment-index="1" --></span> ---- ### 1-100所有2的次方數 :heavy_check_mark: <span> ```python= [2**i for i in range(10) if 2**i < 101 and 2**i > 0] ``` <!-- .element: class="fragment" data-fragment-index="1" --></span> ---- ### DNA 處理:把輸入不可能出現的鹼基濾掉 Ex: 輸入 `ATCGATGCHATGCATFC` 輸出 `ATCGATGCATGCATC` ---- :x: ```python= k = input() new_k = '' for i in k: if i in 'ATGC': new_k+=i ``` ---- :heavy_check_mark: ```python= ''.join([i for i in input() if i in 'ATGC']) ``` --- ## 進階 List Comprehension ---- ### 印出9x9乘法表 :x: ```python= for i in range(1, 10): for j in range(1, 10): print(i, j, i * j) ``` ---- :heavy_check_mark: 巢狀 for ```python= # 遍歷 i:for i in range(1, 10) # 遍歷 j:for j in range(1, 10) [print(i, j, i * j) for i in range(1, 10) for j in range(1, 10)] ``` ---- ### 用 list 存一個 5x5 Identity Matrix (對角線為 1 的矩陣) 就是這個: $$ \begin{bmatrix} 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 \end{bmatrix} $$ ---- :x: ```python= identity = [] for i in range(5): row = [] for j in range(5): row.append(1 if i == j else 0) identity.append(row) ``` ---- :heavy_check_mark: 巢狀 list comprehension! ```python= [[1 if i == j else 0 for i in range(5)] for j in range(5)] ``` ---- 結束了? --- ## Tricks ---- ### Conditional Expression 一行版的 if else :x: ```python= x = 3 if x % 2 == 0: k = x else: k = x + 1 ``` :heavy_check_mark: ```python= x = 3 k = x if x % 2 == 0 else x + 1 ``` ---- 巢狀 if else 也可以ㄛ :x: ```python= x = 5 if x % 3 == 0: k = 'A' else: if x % 3 == 1: k = 'B' else: k = 'C' ``` :heavy_check_mark: ```python= x = 5 k = 'A' if x % 3 == 0 else \ 'B' if x % 3 == 1 else 'C' ``` ---- ## 解說 ```python= 'B' if x % 3 == 0 else ('B' if x % 3 == 1 else 'C') # 回傳 ('B' if x % 3 == 1 else 'C') ('B' if x % 3 == 2 else 'C') # 回傳 'B' ``` ---- ### zip 把東西一起迭代 :x: ```python= a = [1, 2, 3] b = ['e', 'a', 't'] for i in range(3): print(a[i], b[i]) ``` :heavy_check_mark: ```python= a = [1, 2, 3] b = ['e', 'a', 't'] for i, j in zip(a, b): print(i, j) ``` ---- 多個、不同長度也可以ㄛ ```python= a = [1, 2, 3] b = ['e', 'a', 't'] for i, j, k in zip(a, b, range(5)): print(i, j, k) ``` ``` 1 e 0 2 a 1 3 t 2 ``` ---- ### star expression 把東西展開(? 比如說我們要把一個 list 裡面的元素印出來,中間用空白隔開 Ex: [1, 2, 3] -> `1 2 3` ---- :x: ```python3= a = [3, 1, 2] for i, j in enumerate(a): if i != len(a) - 1: print(j, end=' ') else: print(j, end='\n') ``` ---- :heavy_check_mark: ```python3= a = [3, 1, 2] print(*a) ``` `print(*a)` 等價於 `print(3, 1, 2)` ---- 這些跟 list comprehension 有什麼關係? --- ## List Comprehension ft. Tricks 一行解! ---- ### DNA 處理 2:把輸入不可能出現的鹼基換成 'x' Ex: 輸入 `ATCGATGCHATGCATFC` 輸出 `ATCGATGCxATGCATxC` ---- :x: ```python= k = input() new_k = '' for i in k: if i in 'ATGC': new_k +=i else: new_k += 'x' ``` ---- :heavy_check_mark: ```python= ''.join([i if i in 'ATGC' else 'x' for i in input()]) ``` ---- ### DNA 處理 3:輸入兩個一樣長 DNA 序列,輸出不一樣的位置 Ex: 輸入 `ATCGC` 和 `ATCCG`,輸出 `4 5` ---- :x: ```python= s1 = input() s2 = input() ans = [] for i in range(len(s1)): if s1[i] != s2[i]: ans.append(i + 1) for i, j in enumerate(ans): if i != len(ans) - 1: print(j, end=' ') else: print(j, end='\n') ``` ---- :heavy_check_mark: ```python= # 一起迭代:zip(input(), input()) # 獲得 index:enumerate(zip(input(), input())) # 判斷是否不同:j != k # 印出 list:print(*[]) print(*[i + 1 for i, (j, k) in enumerate(zip(input(), input())) if j != k]) ``` ---- ### 印出9x9乘法表的其中幾行 :x: ```python= for i in range(1, 10): if i in [2, 3, 5, 7]: for j in range(1, 10): print(i, j, i * j) ``` ---- :heavy_check_mark: ```python= [print(i, j, i * j) for i in range(1, 10) if i in [2, 3, 5, 7] for j in range(1, 10)] ``` --- ## 沒講的東西 * Dict Comprehension * Set Comprehension --- ## Summary ---- ### Pros * 潮 * 快(會被Python優化) * 看起來像大神 ---- ### Cons * 可讀性低落 * 腦子很累 --- ## More Practice 試著將之前出的題目一行解吧!
{"metaMigratedAt":"2023-06-15T09:46:35.867Z","metaMigratedFrom":"YAML","title":"List Comprehension","breaks":true,"slideOptions":"{\"theme\":\"dark\",\"transition\":\"fade\"}","contributors":"[{\"id\":\"3d3e812e-7132-40aa-b06f-8f5380bf64d1\",\"add\":9596,\"del\":4080}]"}
    990 views