【Python】リスト・辞書・集合・タプルの比較

Pythonの主要なデータ構造である リスト（list）、辞書（dict）、集合（set）、タプル（tuple）について、それぞれの特徴を比較しながら、サンプルコードを交えて初心者にも分かりやすく説明します。
# 作成方法と基本的な使い方
```python
# リスト (list)
fruits_list = ['apple', 'banana', 'orange']

# 辞書 (dict)
person_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}

# 集合 (set)
unique_numbers_set = {1, 2, 3, 4, 5}

# タプル (tuple)
coordinates_tuple = (10, 20)

print("リスト:", fruits_list)
print("辞書:", person_dict)
print("集合:", unique_numbers_set)
print("タプル:", coordinates_tuple)
```
# 要素へのアクセス
```python
# リスト: インデックスでアクセス
print("リストの2番目の要素:", fruits_list[1])
# 出力: リストの2番目の要素: banana

# 辞書: キーでアクセス
print("辞書の'name'キーの値:", person_dict['name'])
# 出力: 辞書の'name'キーの値: Alice

# 集合: 直接アクセスはできない（存在確認は可能）
print("集合に3が含まれるか:", 3 in unique_numbers_set)
# 出力: 集合に3が含まれるか: True

# タプル: インデックスでアクセス
print("タプルの1番目の要素:", coordinates_tuple[0])
# 出力: タプルの1番目の要素: 10
```
# 変更可能性
```python
# リスト: 変更可能
fruits_list.append('grape')
print("要素追加後のリスト:", fruits_list)
# 出力: 要素追加後のリスト: ['apple', 'banana', 'orange', 'grape']


# 辞書: 変更可能
person_dict['job'] = 'Engineer'
print("キー追加後の辞書:", person_dict)
# 出力: キー追加後の辞書: {'name': 'Alice', 'age': 30, 'city': 'New York', 'job': 'Engineer'}

# 集合: 変更可能
unique_numbers_set.add(6)
print("要素追加後の集合:", unique_numbers_set)
# 出力: 要素追加後の集合: {1, 2, 3, 4, 5, 6}

# タプル: 変更不可
# coordinates_tuple[0] = 30  # これはエラーになります
new_coordinates = coordinates_tuple + (30,)  # 新しいタプルを作成
print("新しいタプル:", new_coordinates)
# 出力: 新しいタプル: (10, 20, 30)
```
# 重複要素の扱い
```python
# リスト: 重複を許可
numbers_list = [1, 2, 2, 3, 3, 4]
print("重複のあるリスト:", numbers_list)
# 出力: 重複のあるリスト: [1, 2, 2, 3, 3, 4]

# 辞書: キーの重複は不可（値の重複は可）
# {'a': 1, 'a': 2} とすると、後者が優先されます

# 集合: 重複を自動的に除去
numbers_set = {1, 2, 2, 3, 3, 4}
print("重複を除去した集合:", numbers_set)
# 出力: 重複を除去した集合: {1, 2, 3, 4}

# タプル: 重複を許可
numbers_tuple = (1, 2, 2, 3, 3, 4)
print("重複のあるタプル:", numbers_tuple)
# 出力: 重複のあるタプル: (1, 2, 2, 3, 3, 4)
```
# 順序の保持
```python
# リスト: 順序を保持
print("リストの順序:", fruits_list)
# 出力: リストの順序: ['apple', 'banana', 'orange', 'grape']

# 辞書: Python 3.7以降は挿入順を保持
print("辞書の順序:", person_dict)
# 出力: 辞書の順序: {'name': 'Alice', 'age': 30, 'city': 'New York', 'job': 'Engineer'}

# 集合: 順序を保持しない
print("集合（順序不定）:", unique_numbers_set)
# 出力: 集合（順序不定）: {1, 2, 3, 4, 5, 6}

# タプル: 順序を保持
print("タプルの順序:", coordinates_tuple)
# 出力: タプルの順序: (10, 20)
```
# 主な用途と特徴
```python
# リスト: 順序付きのデータコレクション
tasks = ['洗濯', '掃除', '買い物']
tasks.sort()
print("ソートされたタスクリスト:", tasks)
# 出力: ソートされたタスクリスト: ['掃除', '洗濯', '買い物']

# 辞書: キーと値のペアを持つデータ
book = {'title': 'Python入門', 'author': '山田太郎', 'price': 2500}
print("本の情報:", book)
# 出力: 本の情報: {'title': 'Python入門', 'author': '山田太郎', 'price': 2500}

# 集合: 重複のないユニークな要素の集まり
fruits_set1 = {'apple', 'banana', 'orange'}
fruits_set2 = {'banana', 'grape', 'kiwi'}
print("フルーツの和集合:", fruits_set1 | fruits_set2)
# 出力: フルーツの和集合: {'grape', 'banana', 'orange', 'kiwi', 'apple'}
print("フルーツの積集合:", fruits_set1 & fruits_set2)
# 出力: フルーツの積集合: {'banana'}

# タプル: 変更不可能な順序付きデータ
point = (3, 4)
x, y = point  # アンパッキング
print(f"x座標: {x}, y座標: {y}")
# 出力: x座標: 3, y座標: 4
```
# 特徴のまとめ
1 リスト（list）
- 順序付き
- 変更可能（ミュータブル）
- インデックスでアクセス
- 重複要素を許可
- 主な用途: 順序が重要なデータの格納、頻繁な追加/削除が必要な場合

2 辞書（dict）
- キーと値のペア
- 変更可能（ミュータブル）
- キーでアクセス
- キーの重複は不可（値の重複は可）
- 主な用途: キーと値の関連付け、高速なルックアップが必要な場合

3 集合（set）
- 順序なし
- 変更可能（ミュータブル）
- インデックスでのアクセス不可
- 重複要素を自動的に除去
- 主な用途: ユニークな要素の管理、集合演算

4 タプル（tuple）
- 順序付き
- 変更不可能（イミュータブル）
- インデックスでアクセス
- 重複要素を許可
- 主な用途: 変更されないデータの格納、多重代入、辞書のキーとして使用

これらのデータ構造の特徴を理解することで、プログラムの要件に応じて適切な構造を選択できます。
例えば、ユニークな要素のみを扱う場合は集合を、キーと値のペアを扱う場合は辞書を、順序が重要で変更が必要な場合はリストを、そして変更不可能なグループ化されたデータにはタプルを使用するといった具合です。
######
参考)　[東京工業大学情報理工学院 Python早見表](https://chokkan.github.io/python/index.html)