Python組み込み関数~Zip~

#はじめに
今回の記事では、Pythonの組み込み関数である「zip関数」について取り上げていきたいと思います。
僕自身以前から「zip関数」の存在を知っていて、なんとなく使っているくらいなので、今回を期に「zip関数」の理解を深めていきたいと思います。

#zip関数とは？
そもそも「zip関数」とはなんでしょうか？
簡単に言えば引数に与えられた複数のリストをまとめるものです。  
もっとしっかり知りたいという方はこちらをご覧ください。
[Python 標準ライブラリ ](https://docs.python.org/ja/3/library/functions.html#zip)

#基本的な使い方
基本的な使い方としては、for文で使うものが上げられます。

```python
#名前と年齢のリストを作成
names = ['sato', 'suzuki', 'ito']
ages = [23, 21, 25]

for name, age in zip(names, ages):
    print('名前:{}, 年齢:{}'.format(name, age))

# 名前:sato, 年齢:23
# 名前:suzuki, 年齢:21
# 名前:ito, 年齢:25
```
このように２つのリストをまとめることができます。

３つのリストでも可能です。

```python
#名前と年齢と出身地のリストを作成
names = ['sato', 'suzuki', 'ito']
ages = [23, 21, 25]
birthplaces = ['東京都', '愛知県', '北海道']

for name, age, birthplace in zip(names, ages, birthplaces):
    print('名前:{}, 年齢:{}, 出身地:{}'.format(name, age, birthplace))

# 名前:sato, 年齢:23, 出身地:東京都
# 名前:suzuki, 年齢:21, 出身地:愛知県
# 名前:ito, 年齢:25, 出身地:北海道
```

リストをまとめたい時に便利なことがわかると思います。

まとめるだけであればもっと短くすることができます。

```python
list(zip(names, ages))
#[('sato', '23'), ('suzuki', '21'), ('ito', '25')]
```
こうするとタプルで返ってきます。

#unzip(元に戻す)
zipでまとめたものを元に戻すにはどうすれば良いでしょうか？
答えは引数に「*」をつければできます。

```python
zips = list(zip(names, ages))
names2, ages2 = zip(*zips)
print(names2)
#('sato', 'suzuki', 'ito')
print(ages2)
#(23, 21, 25)
```
このようにタプルで返ってきます。
リストで出力したい場合は、「list()」で囲めば良いです。

```python
zips = list(zip(names, ages))
names2, ages2 = list(zip(*zips))
print(names2)
#[('sato', 'suzuki', 'ito')]
print(ages2)
#[(23, 21, 25)]
```

#リストの長さが違う時
ではリストの長さが違うときはどのようになるのかみていきましょう。

```python
#名前と年齢のリストを作成
names = ['sato', 'suzuki', 'ito', 'kato', 'saitou']
ages = [23, 21, 25]

for name, age in zip(names, ages):
    print('名前:{}, 年齢:{}'.format(name, age))

# 名前:sato, 年齢:23
# 名前:suzuki, 年齢:21
# 名前:ito, 年齢:25
```
これをみると短い方に合わせていることがわかります。

#リストの長さが違う時に値を埋める
先ほどはリストの長さが違うときは、短い方に合わせることを確認できたと思います。
では、長い方に合わせるのはどうしたら良いのか。
それは「zip_longestモジュール」を使用すればできます。
詳しくはこちらをみてください。
[zip_longestモジュール](https://docs.python.org/ja/3/library/itertools.html#itertools.zip_longest)

ではみていきましょう。

```python
#名前と年齢のリストを作成
names = ['sato', 'suzuki', 'ito', 'kato', 'saitou']
ages = [23, 21, 25]

for name, age in zip_longest(names, ages):
    print('名前:{}, 年齢:{}'.format(name, age))

# 名前:sato, 年齢:23
# 名前:suzuki, 年齢:21
# 名前:ito, 年齢:25
# 名前:kato, 年齢:None
# 名前:saitou, 年齢:None
```
このように「None」で埋められていることが確認できます。
「None」だと味気ないので、代わりに平均年齢を入れていきましょう。

```python
#zip_longestのインポート
from itertools import zip_longest

#名前と年齢のリストを作成
names = ['sato', 'suzuki', 'ito', 'kato', 'saitou']
ages = [23, 21, 25]

#平均年齢を算出
age_mean = sum(ages) // len(ages)

#fillvalueで埋める値を指定
for name, age in zip_longest(names, ages, fillvalue=age_mean):
    print('名前:{}, 年齢:{}'.format(name, age))

# 名前:sato, 年齢:23
# 名前:suzuki, 年齢:21
# 名前:ito, 年齢:25
# 名前:kato, 年齢:23
# 名前:saitou, 年齢:23
```
年齢の平均値で埋められていることが確認できます。

最後に３つ以上のリストの長さがバラバラな時を確認しましょう。

```python
#zip_longestのインポート
from itertools import zip_longest

#名前と年齢と出身地のリストを作成
names = ['sato', 'suzuki', 'ito']
ages = [23, 21, 25]
birthplaces = ['東京都', '愛知県', '北海道', '山梨県']

#平均年齢を算出
age_mean = sum(ages) // len(ages)

#fillvalueで埋める値を指定
for name, age, birthplace in zip_longest(names, ages, birthplaces, fillvalue=age_mean):
    print('名前:{}, 年齢:{}, 出身地:{}'.format(name, age, birthplace))

# 名前:sato, 年齢:23, 出身地:東京都
# 名前:suzuki, 年齢:21, 出身地:愛知県
# 名前:ito, 年齢:25, 出身地:北海道
# 名前:kato, 年齢:23, 出身地:山梨県
# 名前:saitou, 年齢:23, 出身地:23
```
出力結果を確認すると一番最後の行の出身地が「23」になっています。
このように埋める値は１つしかしていできないので注意が必要です。

その際の対策はこの記事を参考にしてください。
[Python, zip関数の使い方: 複数のリストの要素をまとめて取得](https://note.nkmk.me/python-zip-usage-for/)

#最後に
今回は「zip関数」について取り上げました。
お役に立てれば幸いです。
これからも関数やモジュールについての記事を上げていくので、よければ見ていってください。