Pythonのプログラミングにおいて、データを効率的に扱う能力は非常に重要です。この章では、Pythonに組み込まれている強力なコレクション(データ構造)であるリスト、タプル、辞書、セットを学びます。これらのデータ構造は、他の言語における配列、ハッシュマップ、集合などと似ていますが、Pythonならではの便利な特性やメソッドを持っています。これらを理解し、使いこなすことが「Pythonらしい」コードを書くための第一歩です。
リストは、複数の要素を順序付けて格納できるコレクションです。他の言語における「動的配列」に最も近い存在です。
基本的な使い方 (REPL実行例)
>>> # リストの作成
>>> fruits = ['apple', 'banana', 'cherry']
>>> fruits
['apple', 'banana', 'cherry']
>>> # 要素へのアクセス (インデックスは0から)
>>> fruits[1]
'banana'
>>> # 要素の変更
>>> fruits[0] = 'apricot'
>>> fruits
['apricot', 'banana', 'cherry']
>>> # 要素の追加 (末尾に)
>>> fruits.append('mango')
>>> fruits
['apricot', 'banana', 'cherry', 'mango']
>>> # 要素の削除 (指定したインデックス)
>>> removed_fruit = fruits.pop(1)
>>> removed_fruit
'banana'
>>> fruits
['apricot', 'cherry', 'mango']
リストは非常に柔軟性が高く、Pythonで最も頻繁に使われるデータ構造の一つです。
タプルはリストと非常によく似ていますが、最大の違いはイミュータブル (Immutable)、つまり一度作成したら変更できない点です。
なぜタプルを使うのか? 🤔
基本的な使い方 (REPL実行例)
>>> # タプルの作成 (丸括弧を使用) >>> coordinates = (10, 20) >>> coordinates (10, 20) >>> # 要素へのアクセス >>> coordinates[0] 10 >>> # 変更しようとするとエラーが発生する >>> coordinates[0] = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> # アンパッキング (複数の変数に要素を一度に代入) >>> x, y = coordinates >>> x 10 >>> y 20
辞書は、他の言語のハッシュマップや連想配列に相当します。順序ではなく、一意な「キー」を使って「値」にアクセスします。
key: value の形式でデータを格納します。基本的な使い方 (REPL実行例)
>>> # 辞書の作成
>>> person = {'name': 'Taro Yamada', 'age': 30, 'city': 'Tokyo'}
>>> person
{'name': 'Taro Yamada', 'age': 30, 'city': 'Tokyo'}
>>> # 値へのアクセス (キーを使用)
>>> person['name']
'Taro Yamada'
>>> # 値の変更
>>> person['age'] = 31
>>> person['age']
31
>>> # 新しいキーと値のペアの追加
>>> person['job'] = 'Engineer'
>>> person
{'name': 'Taro Yamada', 'age': 31, 'city': 'Tokyo', 'job': 'Engineer'}
>>> # キーと値のペアをまとめて取得
>>> person.items()
dict_items([('name', 'Taro Yamada'), ('age', 31), ('city', 'Tokyo'), ('job', 'Engineer')])
セットは、順序がなく、重複した要素を持たないコレクションです。数学の「集合」の概念に近く、和集合や積集合といった集合演算を高速に行えます。
使いどころ
基本的な使い方 (REPL実行例)
>>> # セットの作成 (重複した4は自動的に無視される)
>>> numbers = {1, 2, 3, 4, 4, 5}
>>> numbers
{1, 2, 3, 4, 5}
>>> # 要素の追加
>>> numbers.add(6)
>>> numbers
{1, 2, 3, 4, 5, 6}
>>> # 重複削除への応用
>>> my_list = ['a', 'b', 'c', 'a', 'b']
>>> unique_elements = set(my_list)
>>> unique_elements
{'c', 'a', 'b'}
>>> # 集合演算
>>> set_a = {1, 2, 3, 4}
>>> set_b = {3, 4, 5, 6}
>>> # 和集合 (A ∪ B)
>>> set_a | set_b
{1, 2, 3, 4, 5, 6}
>>> # 積集合 (A ∩ B)
>>> set_a & set_b
{3, 4}
スライシングは、リストやタプルのようなシーケンスから、部分的な要素を効率的に取り出すための非常に強力な機能です。構文は [start:stop:step] です。
REPL実行例
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> # インデックス1から4の手前まで >>> numbers[1:4] [1, 2, 3] >>> # 最初からインデックス5の手前まで >>> numbers[:5] [0, 1, 2, 3, 4] >>> # インデックス6から最後まで >>> numbers[6:] [6, 7, 8, 9] >>> # 2つおきに要素を取得 >>> numbers[::2] [0, 2, 4, 6, 8] >>> # 逆順にする >>> numbers[::-1] [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
内包表記は、既存のイテラブルから新しいリスト、辞書、セットを簡潔かつ効率的に生成するためのPythonらしい構文です。forループを使うよりも短く、可読性が高いコードを書くことができます。
リスト内包表記
forループで書く場合と、リスト内包表記で書く場合を比較してみましょう。
>>> # forループの場合 >>> squares_loop = [] >>> for i in range(10): ... squares_loop.append(i * i) ... >>> squares_loop [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> # リスト内包表記の場合 (簡潔!) >>> squares_comp = [i * i for i in range(10)] >>> squares_comp [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> # 条件付きも可能 (偶数のみ2乗) >>> even_squares = [i * i for i in range(10) if i % 2 == 0] >>> even_squares [0, 4, 16, 36, 64]
辞書内包表記
>>> # 数値をキー、その2乗を値とする辞書を作成
>>> square_dict = {x: x*x for x in range(5)}
>>> square_dict
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
セット内包表記
>>> # リスト内のユニークな数値の2乗のセットを作成
>>> numbers = [1, 2, 2, 3, 4, 4, 5]
>>> square_set = {x*x for x in numbers}
>>> square_set
{1, 4, 9, 16, 25}
この章では、Pythonでデータを扱うための基本的な4つのコレクションを学びました。それぞれの特性を理解し、状況に応じて適切に使い分けることが重要です。
| データ構造 | 構文例 | 変更可能性 | 順序 | 重複 | 主な用途 |
|---|---|---|---|---|---|
| リスト (List) | [1, 'a', 2] | 可能 (ミュータブル) | あり | 許可 | 順序があり、変更が必要な要素の集まり。 |
| タプル (Tuple) | (1, 'a', 2) | 不可能 (イミュータブル) | あり | 許可 | 変更しない(させたくない)データの集まり、辞書のキー。 |
| 辞書 (Dictionary) | {'key': 'value'} | 可能 (ミュータブル) | あり (Python 3.7+) | キーは不許可 | キーと値のペアでデータを管理。 |
| セット (Set) | {1, 'a', 2} | 可能 (ミュータブル) | なし | 不許可 | 重複を除き、要素の存在確認や集合演算を高速に行う。 |
加えて、スライシングを使えばシーケンス(リストやタプル)から部分的な要素を柔軟に取得でき、内包表記を利用すれば、これらのコレクションを一行で効率的かつPythonらしく生成できます。これらのツールは、あなたのコードをより簡潔で強力なものにしてくれるでしょう。
ある店舗の商品のリストがあります。このリストから、価格が500円以上の商品だけを抽出し、その名前だけを新しいリストに格納してください。
ヒント:
リスト内包表記と、辞書の値にアクセスする方法 (product['price']) を組み合わせ、if 条件を追加してみましょう。
products = [
{'name': 'Apple', 'price': 150},
{'name': 'Banana', 'price': 100},
{'name': 'Melon', 'price': 600},
{'name': 'Orange', 'price': 120},
{'name': 'Grape', 'price': 550}
]
python practice3_1.py(出力例) ['Melon', 'Grape']
2つのクラブ活動、「数学クラブ」と「科学クラブ」のメンバーリストがあります。セット(集合)の機能を使って、以下のメンバーリストを作成してください。
a. 両方のクラブに所属しているメンバー b. 少なくともどちらか一方のクラブに所属している全メンバー c. 数学クラブにのみ所属しているメンバー
ヒント:
セットの積集合 (&)、和集合 (|)、差集合 (-) 演算子を使います。
math_club = {'Alice', 'Bob', 'Charlie', 'David'}
science_club = {'Charlie', 'David', 'Eve', 'Frank'}
python practice3_2.py(出力例)
a. {'Charlie', 'David'}
b. {'Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank'}
c. {'Alice', 'Bob'}