Pythonチュートリアル #3 -細かい用語多すぎないか-

※以下の企画です

https://qiita.com/tatataichi/private/56936a028e625e62af8e


Pythonチュートリアル3回目の学習です。
今回は第5章をやっていきます。テーマは「データ構造」だそうでして、めちゃくちゃ楽しみです。

# 5章　学習内容
## リストの深堀り
既に学習済みのリストに対しての補足。
この項ではlist.copy、list.appendのように配列系のオブジェクトでよく見るメソッドが用意されていることがわかった。メソッドの内容では特に目新しいものはない。

ただ、**リスト内包**については目をずっと背けてきたのでここで改めて学習していく…
### リスト内包
**リスト内包**という方法は、イテラブルなどの連続したデータをシンプルにリストにぶち込む方法っぽい。

例えば以下のような二乗を求めるコードがあったとして…
```python:二乗の計算
>> squares = []
>> for x in range(10):
>>   squares.append(x**2)
>> print(squares)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

これだと長いので…

```python:リスト内包
>> squares_2 = [x**2 for x in range(10)]
>> print(squares_2)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```

という感じでまとめて書こうぜ！ってのがリスト内包らしい。
文法の意味としては、「**最初に処理式を書いて、その後にforやifで評価する**」というもの。
超スマートなので良いなぁと思いつつ、第三者にとって分かりづらくないか？という気持ちもある。
真のパイソニアン以外には好まれないのでは？と思って色々ネット記事を調べてみたが、同じ意見の人もまぁまぁいたw
僕のようにPython出身じゃない異国民は反発する傾向にあるようだ。
**ということでリスト内包はまた蓋を閉める。**

## タプルとシーケンス
**タプル**というものはカンマで区切られたデータのあつまりのことを言うらしい。
それを理解するためには**シーケンス型**という基となっているデータ構造の理解が必要そう。
本書だけでは全く理解できなかったので、いつもの如くChat GPT君にも聞いてみた。

### シーケンス型とは？ from GPT
Pythonにおけるシーケンス型は、複数の要素を順番に並べたデータ構造を表現します。
代表的なシーケンス型には、以下のものがあります
1. リスト (list)
2. タプル (tuple)
3. 文字列 (str)
4. レンジ (range)

シーケンス型の特徴：
* 順序を持つ（各要素にはインデックスがあり、順序を維持する）
* ミュータブル（変更可能）なものもあれば、イミュータブル（変更不可能）なものもある

…とのこと。
とにかく連続したデータで上記条件を満たすものは全てシーケンス型という原理原則があると覚えておいてみる。
また、リスト型はミュータブルで、タプルはイミュータブルらしい。

### タプルとは？ from GPT
タプル (tuple) は、Pythonのシーケンス型の一つで、イミュータブル（変更不可能）なデータ構造です。
つまり、一度作成されたタプルの内容を変更することはできません。

タプルの基本的な特徴：
* **イミュータブル**: 一度生成したタプルの中の値を後から変更することはできません。そのため、変更されては困るようなデータの集まりを表現するのに適しています
* **要素へのアクセス**: リストと同様、インデックスを使って要素にアクセスします
* **複数の型の要素を持てる**: 一つのタプルに異なる型（整数、文字列、リストなど）の要素を含めることが可能です

…とのこと。
リストとの違いは、**ミュータブル**か**イミュータブル**かで、**タプルは変更されることがない値を保存しておく際に適している**らしい。**const**みたいなものかな？

```python:tuple
>> t = (0,123,"Hello",0.1)
>> print(t)

(0, 123, 'Hello', 0.1)

>> print(t[2])

Hello

>> t[0] = 1

---------------------------------------------------------------------------
TypeError                                 
Traceback (most recent call last)
<ipython-input-8-c8aeb8cd20ae> in <cell line: 1>()
----> 1 t[0] = 1

TypeError: 'tuple' object does not support item assignment
```

## ディクショナリ型のテクニック
Pythonにはディクショナリ型という素敵なデータ構造があり、`キー値：値`という形式でデータを束ねることができる。
普段からめちゃくちゃ使っており本書のこの章でも登場してきて、いくつか便利なメソッド等も紹介されていたのでまとめてみる。

### itemメソッド
itemメソッドは、キー値と紐づく値をセットで取り出せるメソッド。ループなどの構文で有用そうだ。

```python:itemメソッド
>> post = {'Alice':4346, 'Bob':4347, 'Carol':4348}
>> for n,m in post.items():
>>   print(n,m)
  
Alice 4346
Bob 4347
Carol 4348
```

### enumerate関数
インデックスも合わせて表示したいときは、`enumerate`関数を使う
`enumerate`関数は、Pythonの組み込み関数の一つで、イテラブルに対してループ処理時にインデックス番号を割り振ってくれる関数っぽい。

以下はディクショナリ型ではなく、リスト型だがディクショナリ型でも使える。

```python:enumerate()
>> name = ['Alice', 'Bob', 'Carol']
>> for index, value in enumerate(name):
>>   print(index,value)

0 Alice
1 Bob
2 Carol
```

### zip関数
`zip`関数は`enumerate`と同様に組み込み関数の一つで、複数のイテラブルを並列に処理できる。
要は、２つのイテラブルデータを組み合わせたループ処理ができる。

```python:zip()
>> question = ["name?", "age?", "gender?"]
>> answer = ["Alice", "23", "female"]
>> for q,a in zip(question,answer):
>>   print(q,a)

name? Alice
age? 23
gender? female
```

これは便利。indexで細かく管理しなくても、サクサク書いていけそう。

# まとめ
今回の章では、`zip()`や`enumerate()`のようなよく見る関数を学び直せて良かった。
また、タプルとかイミュータブルとかシーケンス型とか細かい用語も拾っていけたので、パイソニアン（と呼ぶのかは知らないけど）に一歩近づけた気がする。
リスト内容や、各種メソッド・組み込み関数を学習するたびに、「**自分は本当にPythonらしいコードを書いてこなかったんだな**」と感じます。C言語的な泥臭い書き方ばかりしていたなと。
for文を使うときは、``i in range(len(list))``という指定をほぼ確実にするし…
しっかり実践もしていきまっす！