「リストと辞書、どっちを使えばいいんだろう?」そんな迷いは、Pythonを学び始めた多くの人が通る道です。
実は、データ構造の選び方が、コードの読みやすさや実行速度を大きく左右します。Pythonにはリスト、タプル、辞書、集合といった便利な入れ物がそろっていて、状況に合わせて選ぶだけで、ムダの少ない気持ちのいいコードになります。
まずは、それぞれの性質と基本の使い方をイメージしやすい例で確認し、そのあとで「どう選ぶか」の目安をまとめていきましょう。自分のケースに当てはめながら読むと、グッと理解が深まります。
では、最も出番の多いリストから見ていきましょう。
リストは順番がある、あとから中身を変えられる入れ物です。
買い物リストのように、順番を保ちながら項目を追加・削除・差し替えしたいときにピッタリです。整数や文字列など種類の違うデータを混ぜて入れても問題ありません。
# リストの作成
fruits = ['apple', 'banana', 'cherry']
# 要素の追加
fruits.append('orange')
# 要素の削除
fruits.remove('banana')
# 要素の変更
fruits[0] = 'grape'
# リストの表示
print(fruits)
このコードでは、最初に3つの文字列からなるリストを作り、あとからオレンジを追加しています。不要になったバナナはremoveで取り除き、先頭の要素はインデックス0を指定してぶどうに差し替えました。printで中身を表示すると、操作の結果がそのまま順番つきで確認できます。順番も大事だし、後から編集もしたいというときは、まずリストを思い出してください。
次に、似ているようで大きく性質が違うタプルを見てみましょう。
タプルは順番はあるけれど、作ったあとに中身を変えない入れ物です。
地図の座標(x, y)や、年月日(year, month, day)のように、ひとかたまりで意味があり、変更の必要がない値に向いています。変更できないぶん、リストより軽くて扱いが速いこともあります。
# タプルの作成
coordinates = (10, 20)
# タプルの要素へのアクセス
x, y = coordinates
# タプルの表示
print(f"X: {x}, Y: {y}")
ここでは座標をタプルで表し、xとyに分解して取り出しています。タプルは「決まった2つ(または複数)の値がセットで動く」ときに読みやすく、安全です。変更できない性質のおかげで、辞書のキーとして使えるなど、後で役立つ場面も出てきます。
次は、名前で値を取り出せる、便利な「引き出し」タイプの辞書です。
辞書はキー(ラベル)と値をペアで持つ入れ物です。
英単語と意味の対応表のように、名前で素早く探したいというときに大活躍します。キーは重複できませんが、値は同じでもかまいません。
# 辞書の作成
person = {
'name': 'Alice',
'age': 30,
'city': 'New York'
}
# 値の取得
name = person['name']
# 値の追加
person['email'] = 'alice@example.com'
# 値の変更
person['age'] = 31
# 辞書の表示
print(person)
この例では、人の情報を「name」「age」「city」といったキーで管理しています。名前の取得はperson['name']のように、ラベルを指定するだけ。あとからemailを足したり、年齢を更新したりするのも簡単です。「項目名で直接アクセスしたい」「検索を速くしたい」と感じたら、辞書を第一候補にしましょう。
最後は、重複を自動でなくしてくれる集合を見てみます。
集合は順番がなく、同じ値を重ねて持たない入れ物です。
リストの中から重複を取り除きたいときや、共通点・違いを調べるような“集合演算”に向いています。ある値が含まれているかどうかのチェックも得意です。
# 集合の作成
numbers = {1, 2, 3, 4, 5}
# 要素の追加
numbers.add(6)
# 要素の削除
numbers.remove(3)
# 集合の表示
print(numbers)
# 他の集合との和集合
other_numbers = {4, 5, 6, 7, 8}
union = numbers.union(other_numbers)
# 和集合の表示
print(union)
このコードでは、重複のない数値の集まりを作り、要素を足したり削ったりしています。さらに、ほかの集合との和集合を求めることで、両方の要素をまとめた結果が得られます。順番に意味がないデータや、重複排除・素早い含有判定が必要なデータに適しています。
ここまでで4つの基本がそろいました。「結局、どれを選べばいいの?」という疑問に、次で答えていきます。
選び方に迷ったときは、次の観点を順番にチェックすると判断しやすくなります。
「先頭に頻繁に追加・削除したい」など特別な操作が多い場合は、標準ライブラリのcollections.dequeのような専用構造が役立つこともあります。まずは基本4種で十分ですが、「操作の回数が多くて遅い」と感じたら、より適した入れ物がないかを探してみましょう。
言葉だけだとピンと来ないこともありますよね。よくある作業を、最適な入れ物でサッと体験してみましょう。
emails = ['a@example.com', 'b@example.com', 'a@example.com']
unique = set(emails)
print('a@example.com' in unique) # True(高速)
print(unique) # {'a@example.com', 'b@example.com'}
リストのままでは同じアドレスが重なりますが、集合にすると一発で重複が消えます。さらに、含まれているかどうかのチェックも集合が得意です。
users = {
101: 'Alice',
102: 'Bob',
103: 'Carol',
}
print(users[102]) # 'Bob'
番号(キー)から名前(値)をすぐに取り出せます。リストを順に探すよりも直感的で高速です。
今回学習した内容をまとめます。
データ構造の選択は「正解がひとつ」ではなく、「目的に合っているか」が大切です。今の用途に合う入れ物を選べば、コードは読みやすく、パフォーマンスも自然と良くなります。あなたのプログラムで一番大事なのは何でしょう? 順序、検索の速さ、重複の扱い、変更のしやすさ。優先順位をはっきりさせれば、選ぶべきデータ構造が見えてきます。