## 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
簡單三步驟
----

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}]"}