2:Python入門のデータ構造 



## Pythonのデータ構造を学ぼう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999291/4c898f28-1f39-491e-a625-5fa6dacfb6bd.png)

---

### クルミとジャービスのPython冒険記 - データ構造編

**クルミ**: ジャービス、前回は Python の基本を学んだけど、今日はどんなことを勉強するの？

**ジャービス**: 今日は Python のデータ構造について学びましょう！データ構造は、データを効率的に格納・操作するための方法です。Python には強力な組み込みデータ構造があり、これらを使いこなせるようになると、プログラミングがもっと楽しくなりますよ。

**クルミ**: データ構造って聞くと難しそう...でも頑張るよ！どんな種類があるの？

**ジャービス**: 主に4つの基本的なデータ構造があります：リスト、タプル、集合、辞書です。それぞれ特徴が異なるので、用途に応じて使い分けることが大切です。まずはリストから見ていきましょう。

---

## リスト (Lists)

**ジャービス**: リストは順序付けられた変更可能なデータのコレクションです。角括弧 `[]` で作成します。

```python
# リストの作成
fish_types = ["マグロ", "サケ", "タイ", "フグ"]
print(fish_types)  # ['マグロ', 'サケ', 'タイ', 'フグ']
```

**クルミ**: なるほど！魚の名前をリストにしたんだね。でも、リストには魚の名前だけじゃなくて、他の種類のデータも入れられるの？

**ジャービス**: もちろんです！リストには異なる型のデータを混ぜて格納することができます。

```python
mixed_list = ["マグロ", 3, 25.5, True]
print(mixed_list)  # ['マグロ', 3, 25.5, True]
```

**クルミ**: すごい！文字列、整数、小数、真偽値が一つのリストに入ってる！でも、リストの中の特定の要素を取り出すにはどうするの？

**ジャービス**: インデックスを使って要素にアクセスします。Python のインデックスは0から始まることを覚えておいてください。

```python
fish_types = ["マグロ", "サケ", "タイ", "フグ"]
print(fish_types[0])  # 'マグロ'
print(fish_types[2])  # 'タイ'
```

**クルミ**: 0から始まるんだね、覚えておくよ。あと、リストの最後の要素を取り出すときはどうするの？

**ジャービス**: 負のインデックスを使うと、リストの末尾から要素にアクセスできます。-1が最後の要素、-2が最後から2番目の要素という具合です。

```python
fish_types = ["マグロ", "サケ", "タイ", "フグ"]
print(fish_types[-1])  # 'フグ'
print(fish_types[-2])  # 'タイ'
```

**クルミ**: 便利だね！リストを変更することもできるの？

**ジャービス**: はい、リストは変更可能（ミュータブル）なので、要素の追加、削除、変更ができます。

```python
fish_types = ["マグロ", "サケ", "タイ", "フグ"]

# 要素の変更
fish_types[1] = "カツオ"
print(fish_types)  # ['マグロ', 'カツオ', 'タイ', 'フグ']

# 要素の追加
fish_types.append("サバ")
print(fish_types)  # ['マグロ', 'カツオ', 'タイ', 'フグ', 'サバ']

# 特定の位置に挿入
fish_types.insert(2, "イワシ")
print(fish_types)  # ['マグロ', 'カツオ', 'イワシ', 'タイ', 'フグ', 'サバ']

# 要素の削除
fish_types.remove("タイ")
print(fish_types)  # ['マグロ', 'カツオ', 'イワシ', 'フグ', 'サバ']
```

**クルミ**: わかりやすい！リストは本当に便利だね。他にも便利な機能はある？

**ジャービス**: リストのスライスという機能もあります。これを使うと、リストの一部を取り出すことができます。

```python
fish_types = ["マグロ", "サケ", "タイ", "フグ", "サバ", "イワシ"]

# スライス [開始:終了:ステップ]
print(fish_types[1:4])    # ['サケ', 'タイ', 'フグ']
print(fish_types[:3])     # ['マグロ', 'サケ', 'タイ']
print(fish_types[3:])     # ['フグ', 'サバ', 'イワシ']
print(fish_types[::2])    # ['マグロ', 'タイ', 'サバ']
```

**クルミ**: スライスもすごく便利！特に `::2` で1つおきに取り出せるのが面白いね。

**ジャービス**: そうですね。また、リストの内包表記という機能もあります。これを使うと、既存のリストから新しいリストを簡潔に作成できます。

```python
# 基本的な内包表記
squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 条件付き内包表記
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)  # [0, 4, 16, 36, 64]

# 魚の例
fish_lengths = [15, 25, 10, 30, 20]
big_fish = [length for length in fish_lengths if length > 20]
print(big_fish)  # [25, 30]
```

**クルミ**: 内包表記はちょっと複雑に見えるけど、すごく便利そう！一行でたくさんのことができるんだね。

---

## タプル (Tuples)

**ジャービス**: 次はタプルについて見ていきましょう。タプルはリストと似ていますが、作成後に変更することができません（イミュータブル）。丸括弧 `()` で作成します。

```python
# タプルの作成
fish_data = ("マグロ", 25.5, 3)
print(fish_data)  # ('マグロ', 25.5, 3)

# 単一要素のタプル（カンマが必要）
single_item_tuple = ("コイ",)
print(single_item_tuple)  # ('コイ',)
```

**クルミ**: タプルはリストと似てるけど、変更できないんだね。でも、なぜ変更できないタプルが必要なの？

**ジャービス**: 良い質問です！タプルは変更できないため、データの安全性が保証されます。また、タプルはハッシュ可能なので、辞書のキーとして使用できます。さらに、タプルは通常、異なる型の関連データを格納するために使用されます。

```python
# 関数から複数の値を返す
def get_fish_stats():
    return "マグロ", 25.5, 3  # これは暗黙的にタプルを返します

name, length, age = get_fish_stats()
print(f"{name}は{age}歳で、長さは{length}cmです。")  # マグロは3歳で、長さは25.5cmです。
```

**クルミ**: なるほど！複数の値を一度に返せるのは便利だね。タプルのアンパックって何？

**ジャービス**: タプルのアンパックとは、タプルの要素を個別の変数に分解することです。先ほどの例でも使いましたが、もう少し詳しく見てみましょう。

```python
fish_data = ("マグロ", 25.5, 3)

# タプルのアンパック
name, length, age = fish_data
print(name)    # 'マグロ'
print(length)  # 25.5
print(age)     # 3

# 一部の要素を無視
name, _, _ = fish_data
print(name)  # 'マグロ'

# 残りの要素をリストとして取得
first, *rest = fish_data
print(first)  # 'マグロ'
print(rest)   # [25.5, 3]
```

**クルミ**: アンパックは本当に便利だね！特に `*rest` の使い方が面白いよ。

---

## 集合 (Sets)

**ジャービス**: 次は集合について見ていきましょう。集合は順序なしの一意な要素のコレクションです。重複を許さず、数学的な集合演算をサポートしています。中括弧 `{}` で作成します。

```python
# 集合の作成
fish_types = {"マグロ", "サケ", "タイ", "フグ", "マグロ"}
print(fish_types)  # {'マグロ', 'サケ', 'タイ', 'フグ'} (重複は自動的に削除)

# 空の集合
empty_set = set()  # 注意: {} は空の辞書を作成する
```

**クルミ**: 集合は重複を自動的に削除するんだね！他にどんな特徴があるの？

**ジャービス**: 集合の最も強力な機能は、数学的な集合演算をサポートしていることです。和集合、積集合、差集合などの操作が簡単にできます。

```python
freshwater_fish = {"コイ", "フナ", "ウナギ", "アユ"}
saltwater_fish = {"マグロ", "サケ", "タイ", "フグ", "ウナギ"}

# 和集合 (Union)
all_fish = freshwater_fish | saltwater_fish
print(all_fish)  # {'コイ', 'フナ', 'ウナギ', 'アユ', 'マグロ', 'サケ', 'タイ', 'フグ'}

# 積集合 (Intersection)
common_fish = freshwater_fish & saltwater_fish
print(common_fish)  # {'ウナギ'}

# 差集合 (Difference)
only_freshwater = freshwater_fish - saltwater_fish
print(only_freshwater)  # {'コイ', 'フナ', 'アユ'}
```

**クルミ**: すごい！数学の集合と同じように使えるんだね。これは便利そう！

**ジャービス**: そうですね。集合は重複を削除したり、共通の要素を見つけたりするのに最適です。また、メンバーシップテスト（要素が含まれているかの確認）も高速です。

```python
# メンバーシップテスト
print("マグロ" in saltwater_fish)  # True
print("コイ" in saltwater_fish)    # False
```

**クルミ**: 集合は特定の要素が含まれているかを素早く確認できるんだね。これは検索に便利そう！

---

## 辞書 (Dictionaries)

**ジャービス**: 最後に辞書について見ていきましょう。辞書はキーと値のペアのコレクションです。各キーは一意で、値にマッピングされています。中括弧 `{}` とコロン `:` で作成します。

```python
# 辞書の作成
fish_info = {
    "name": "マグロ",
    "weight": 80.5,
    "length": 150,
    "is_fresh": True
}
print(fish_info)  # {'name': 'マグロ', 'weight': 80.5, 'length': 150, 'is_fresh': True}
```

**クルミ**: 辞書は実際の辞書みたいに、キーワード（キー）から情報（値）を探せるんだね！どうやって値にアクセスするの？

**ジャービス**: キーを使って値にアクセスします。

```python
# 値へのアクセス
print(fish_info["name"])  # 'マグロ'
print(fish_info["weight"])  # 80.5

# get() メソッドを使用（キーが存在しない場合はデフォルト値を返す）
print(fish_info.get("color", "不明"))  # '不明'
```

**クルミ**: `get()` メソッドは便利だね！キーが存在しない場合にエラーを避けられるんだね。辞書も変更できるの？

**ジャービス**: はい、辞書は変更可能です。キーと値のペアの追加、削除、更新ができます。

```python
fish_info = {"name": "マグロ", "weight": 80.5}

# 項目の追加/更新
fish_info["length"] = 150
fish_info["weight"] = 85.2
print(fish_info)  # {'name': 'マグロ', 'weight': 85.2, 'length': 150}

# 項目の削除
del fish_info["weight"]
print(fish_info)  # {'name': 'マグロ', 'length': 150}
```

**クルミ**: 辞書も便利だね！辞書のループ処理はどうするの？

**ジャービス**: 辞書のループ処理には、`keys()`、`values()`、`items()` メソッドが便利です。

```python
fish_info = {
    "name": "マグロ",
    "weight": 80.5,
    "length": 150,
    "is_fresh": True
}

# キーでループ
for key in fish_info:
    print(key, fish_info[key])

# items() メソッドを使用
for key, value in fish_info.items():
    print(key, value)
```

**クルミ**: なるほど！`items()` を使うと、キーと値の両方に一度にアクセスできるんだね。

**ジャービス**: そうです。また、辞書の内包表記も使えます。これを使うと、既存の辞書から新しい辞書を簡潔に作成できます。

```python
# 辞書の内包表記
fish_lengths = {"マグロ": 150, "サケ": 80, "タイ": 40, "フグ": 30, "サバ": 60}
big_fish = {name: length for name, length in fish_lengths.items() if length > 50}
print(big_fish)  # {'マグロ': 150, 'サケ': 80, 'サバ': 60}
```

---

## ネストしたデータ構造

**クルミ**: これまでの4つのデータ構造、すごく便利だね！でも、もっと複雑なデータを扱いたい場合はどうするの？

**ジャービス**: 良い質問です！Python のデータ構造は互いにネストさせることができます。これにより、複雑なデータモデルを作成することができます。

```python
# 魚市場のデータ
fish_market = {
    "name": "築地市場",
    "location": "東京",
    "sections": [
        {
            "name": "マグロ専門",
            "inventory": [
                {"name": "クロマグロ", "price": 12000, "stock": 3},
                {"name": "メバチマグロ", "price": 8000, "stock": 5}
            ]
        },
        {
            "name": "白身魚",
            "inventory": [
                {"name": "タイ", "price": 4000, "stock": 10},
                {"name": "ヒラメ", "price": 5000, "stock": 8}
            ]
        }
    ]
}

# アクセス例
print(fish_market["name"])  # '築地市場'
print(fish_market["sections"][0]["name"])  # 'マグロ専門'
print(fish_market["sections"][1]["inventory"][0]["name"])  # 'タイ'
```

**クルミ**: すごい！辞書の中にリストがあって、そのリストの中に辞書があるんだね。これで複雑なデータも扱えそう！

---

## データ構造の選択

**クルミ**: 4つのデータ構造を学んだけど、どれを使えばいいか迷うことがありそう...どうやって選べばいいの？

**ジャービス**: データ構造の選択は、データの性質と必要な操作によって決まります。簡単なガイドラインを紹介しましょう：

1. **リスト**：順序が重要で、要素が変更される可能性がある場合
   - 例：魚の名前のリスト、釣った魚の記録

2. **タプル**：順序が重要で、要素が変更されない場合
   - 例：魚の座標 (x, y, z)、RGB色値

3. **集合**：順序が重要でなく、重複を許さない場合
   - 例：釣った魚の種類（重複なし）、共通の魚を見つける

4. **辞書**：キーと値のマッピングが必要な場合
   - 例：魚の詳細情報、在庫管理

**クルミ**: わかりやすい説明ありがとう！これで適切なデータ構造を選べそうだよ。

---

## まとめ

**ジャービス**: 今日は Python の主要なデータ構造について学びました。リスト、タプル、集合、辞書はそれぞれ異なる特徴を持ち、適切に使い分けることが重要です。

**クルミ**: 今日学んだことをまとめると：
- **リスト**：順序付けられた変更可能なコレクション `[1, 2, 3]`
- **タプル**：順序付けられた変更不可能なコレクション `(1, 2, 3)`
- **集合**：順序なしの一意な要素のコレクション `{1, 2, 3}`
- **辞書**：キーと値のペアのコレクション `{"a": 1, "b": 2}`

**ジャービス**: 素晴らしいまとめです！これらのデータ構造を使いこなせるようになると、Python プログラミングがもっと楽しくなりますよ。

**クルミ**: 次回は何を学ぶの？

**ジャービス**: 次回は関数とモジュールについて学びます。これらを使うと、コードをより整理された再利用可能な形で書くことができます。

**クルミ**: 楽しみにしてるよ！今日はありがとう、ジャービス！

---

### 練習問題

1. 5種類の日本の魚のリストを作成し、アルファベット順にソートしてください。
2. 魚の名前と価格のタプルのリストを作成し、価格が高い順にソートしてください。
3. 淡水魚と海水魚の集合を作成し、両方に生息できる魚を見つけてください。
4. 魚の名前をキー、その特性（価格、重さ、原産地など）を値とする辞書を作成してください。
5. 魚市場のデータ構造を作成し、特定のセクションの在庫を表示する関数を作成してください。

---

次回もお楽しみに！

---