# List - 列表生成式( List Comprehensions )
###### tags: `Python`
## 基本形式:
串列生成式的意義在於每次從迭代的項目當中取出一個單項,
接下來將這個單項透過算式進行加工處理,才放到list當中。
:::info
基本的な書き方
リスト・コンプリヘンションは、リスト内包表記とも呼ばれます。これは、ループを利用してイテラブルオブジェクトから一つの要素を取り出し、その要素に対して処理を行って算出してから、リストへ追加する構文です。
:::
```
新列表 = [something for x in 舊列表(或可迭代物件)]
```
:::info
新たなリスト = [要素を算出する式 for x in 旧リスト(または、イテラブルオブジェクト)]
:::
等価なfor文:
```
新列表 = []
for x in 舊列表(或可迭代物件):
新列表.append(something)
```
:::info
新たなリスト = []
for x in 旧リスト(または、イテラブルオブジェクト):
新たなリスト.append(something)
:::
**Example:**
```python=
list(range(9))
# [0, 1, 2, 3, 4, 5, 6, 7, 8]
[i for i in range(9)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8]
```
## Example - 生成1~10的平方數
:::info
Example - 1~10の平方数を生成して下さい。
:::
[1x1, 2x2, 3x3, ..., 10x10]
### 使用迴圈
:::info
ループを使います。
:::
```python=
array = []
for x in range(1, 11):
array.append(x * x)
print(array)
```
### 列表生成式
:::info
List Comprehensions(リスト・コンプリヘンション)
:::
```python=
array = [x * x for x in range(1, 11)]
print(array)
```
## Example - 將字串轉為字元陣列
:::info
Example - 文字列を文字配列にします。
:::
['H', 'e', 'l', 'l', 'o']
```python=
s = "Hello"
[c for c in s] #亦可直接寫 list(s)
```
## Example - 雙for迴圈生成全部的排列組合
:::info
Example - ダブルループですべての組み合わせを生成します。
:::
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
```python=
[m + n for m in 'abc' for n in '123']
```
## 加上 if ... else 判斷
可以用if條件式來進行過濾,只要在後面加上if條件式即可。
:::info
if ... elseを加えます。
ifの条件式を利用して選り分けます。
後ろにifの条件式を追加すれば良いです。
:::
```
新列表 = [something for x in 舊列表(或可迭代物件) if 條件判斷句]
```
### if 判斷
輸出1 ~ 10 中偶數的平方。
:::info
if判断
1~10の偶数の平方数を出力します。
:::
```python=
array = [x * x for x in range(1, 11) if x % 2 == 0]
print(array)
```
### 過濾式加上 else(SyntaxError)
因為for的後面只是篩選所以不能加上else。
:::info
if節にelseを追加するとSyntaxErrorになります。
forの後ろは単に選別しているだけなので、elseを加えることはできません。
:::
```python=
>>> [x for x in range(1, 11) if x % 2 == 0 else 0]
File "<stdin>", line 1
[x for x in range(1, 11) if x % 2 == 0 else 0]
^
SyntaxError: invalid syntax
```
### 表達式加上 if 但沒加else(SyntaxError)
表達式必須要靠後面的變數x算出結果,單用 x if x % 2 == 0 沒辦法根據x算出結果所以要加上else。
:::info
要素を算出する式にifを加え、elseがない場合(SyntaxError)
要素を算出する式の結果は後ろの変数Xにより算出されます。従って、x if x % 2 == 0 のみでは算出できないので、else を加えます。
:::
```python=
>>> [x if x % 2 == 0 for x in range(1, 11)]
File "<stdin>", line 1
[x if x % 2 == 0 for x in range(1, 11)]
^
SyntaxError: invalid syntax
```
將 1 ~ 10 中的基數變為負的。
:::info
1 ~ 10の奇数を負数にします。
:::
```
>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
```
## 多層的list或者組合性質的東西
利用多重的for in來製造出雙層的list或者組合性質的東西。
我們前面提到過list裡面的element也可以是list。
:::info
多重リスト、または複数の要素を持つ組み合わせ
多重のfor inを利用して二重のリスト、または複数の要素を持つ組み合わせを作成します。この前話した通り、リストのElementはリストでもいいです。
:::
### 組4 * 3的格子,格子裡只放零
:::info
4*3のマスを生成し、マスに0を入れます。
:::
```python=
[[0 for i in range(3)] for j in range(4)]
# 等於[0, 0, 0]重複4次
```
```
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
```
### 座標(從(0, 0)起算到(x, y))的組合寫到一個list
:::info
座標(0, 0)から(x, y)までの組み合わせをリストとして出力します。
:::
```python=
x = 4
y = 3
combo = [(row, col) for row in range(x) for col in range(y)]
# 留意4跟3的順序
print(combo)
```
```
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2)]
```
## 列表生成式應用例子
### 全排列組合
輸出'ABC'跟'abc'全字母的排列組合
:::info
すべての組み合わせ
'ABC'と'abc'の英文字の組み合わせをすべて出力します。
:::
```python=
array = [x + y for x in 'ABC' for y in 'abc']
print(array)
```
### 迭代多個變數
:::info
複数の変数を反復します。
:::
* **for**
```python=
dir = {'BGD': 'BanG Dream!', 'ML': 'THE IDOLM@STER MILLION LIVE! ', 'CGSS': 'シンデレラガールズ'}
for k, v in dir.items():
print("{:<5s} = {}".format(k, v))
```
* **列表生成式**
```python=
dir_list = [k + " = " + v for k, v in dir.items()]
print(dir_list)
```
### string function
將list 裡的所有字轉成小寫
:::info
リストの英文字をすべて小文字にします。
:::
```python=
L = ['Hello', 'World', 'IBM', 'Apple']
L_lower = [s.lower() for s in L]
print(L_lower)
```
### Exercise
```python=
#Exercise:
L1 = ['Hello', 'World', 18, 'Apple', None]
print(L2)
if L2 == ['hello', 'world', 'apple']:
print('ok')
else:
print('failure')
```
```python=
#solution:
L2 = [s.lower() for s in L1 if isinstance(s, str)]
```
### Exercise - 二維
:::info
二重
:::
```
範例輸入
5
10
範例輸出
0 1 2 3 4 5 6 7 8 9
-1 0 1 2 3 4 5 6 7 8
-2 -1 0 1 2 3 4 5 6 7
-3 -2 -1 0 1 2 3 4 5 6
-4 -3 -2 -1 0 1 2 3 4 5
```
```python=
#solution:
rows = int(input())
cols = int(input())
li = [[i-j for i in range(0, cols)] for j in range(rows)]
for i in li:
for j in i:
print("{:>4d}".format(j), end="")
print()
```
## 資料
Jp
https://note.nkmk.me/python-list-comprehension/
我參考的(sam)
https://www.atmarkit.co.jp/ait/articles/1905/31/news015_4.html