リストの基本

これまでのレッスンでは、変数は 1 つの値しか保持できませんでした。しかし現実のデータが単体で存在することはめったにありません——買い物かごには複数のアイテム、リーダーボードには複数のエントリ、記事には複数の段落があります。リストは「データの集まり」を保持するために設計されています。Python で最も柔軟でよく使われるデータ構造です。


1. リストとは

リストは角括弧 [] で定義し、要素をカンマで区切ります。異なる型の要素を保持できます:

PYTHON
# 整数のリスト
numbers = [1, 2, 3, 4, 5]

# 文字列のリスト
fruits = ["apple", "banana", "orange"]

# 混在型
mixed = [1, "hello", True, 3.14]

# 空のリスト
empty = []

print(numbers)   # [1, 2, 3, 4, 5]
print(fruits)    # ['apple', 'banana', 'orange']
print(empty)     # []
💡 リストは順序付けられています —— 要素は追加した順序を維持し、固定された位置を持ちます。セットとは異なり、リストの要素は繰り返し可能です。


2. インデックスアクセス

リストのインデックスは文字列とまったく同じように機能します——0 から始まり、負のインデックスをサポートします:

PYTHON
fruits = ["apple", "banana", "orange", "grape", "watermelon"]

# 正のインデックス:0 から始まる
print(fruits[0])      # apple
print(fruits[2])      # orange
print(fruits[4])      # watermelon

# 負のインデックス:-1 から始まる(最後)
print(fruits[-1])     # watermelon
print(fruits[-2])     # grape
print(fruits[-5])     # apple

範囲外のインデックスにアクセスするとエラーになります:

PYTHON
# print(fruits[10])   # IndexError: list index out of range

例:リスト要素情報の取得(難易度 ⭐)

PYTHON
# 学生リストが与えられた
students = ["Alice", "Bob", "Charlie", "David", "Eve"]

# 最初と最後
first = students[0]
last = students[-1]
print(f"First student: {first}")
print(f"Last student: {last}")

# 最初の 3 人
top3 = students[:3]           # スライス
print(f"Top 3: {top3}")

# リストの長さ
count = len(students)
print(f"Total students: {count}")
▶ 試してみよう

3. リストの CRUD 操作

リストはミュータブル(変更可能)です——文字列とは異なり、その場で変更できます。

要素の追加

PYTHON
# append() — 末尾に追加
cities = ["Beijing", "Shanghai"]
cities.append("Guangzhou")
print(cities)               # ['Beijing', 'Shanghai', 'Guangzhou']

# insert() — 特定の位置に挿入
cities.insert(1, "Shenzhen")
print(cities)               # ['Beijing', 'Shenzhen', 'Shanghai', 'Guangzhou']

# extend() — 別のリストをマージ
more_cities = ["Hangzhou", "Chengdu"]
cities.extend(more_cities)
print(cities)               # ['Beijing', 'Shenzhen', 'Shanghai', 'Guangzhou', 'Hangzhou', 'Chengdu']

要素の削除

PYTHON
# pop() — 指定位置の要素を削除して返す(デフォルトは最後)
cities = ["Beijing", "Shanghai", "Guangzhou", "Shenzhen"]
last = cities.pop()         # 最後を削除して返す
print(f"Removed: {last}")   # Shenzhen
print(cities)               # ['Beijing', 'Shanghai', 'Guangzhou']

first = cities.pop(0)       # 最初を削除
print(f"Removed: {first}")  # Beijing
print(cities)               # ['Shanghai', 'Guangzhou']

# remove() — 最初に一致する値を削除
cities = ["Beijing", "Shanghai", "Guangzhou", "Shanghai"]
cities.remove("Shanghai")   # 最初の「Shanghai」のみ削除
print(cities)               # ['Beijing', 'Guangzhou', 'Shanghai']

# clear() — すべての要素を削除
cities.clear()
print(cities)               # []

要素の変更

PYTHON
scores = [60, 70, 80, 90]
scores[2] = 85              # 3 番目を 85 に変更
print(scores)               # [60, 70, 85, 90]

要素の検索

PYTHON
# in — 要素の存在を確認
fruits = ["apple", "banana", "orange"]
print("apple" in fruits)    # True
print("grape" in fruits)    # False

# index() — 位置を検索
print(fruits.index("banana")) # 1
# print(fruits.index("grape"))  # ValueError!
⚠️ 補足:存在しない要素に対して index() を使うとエラーになります。安全に確認するには、最初に in を使いましょう。

例:買い物かご管理(難易度 ⭐⭐)

PYTHON
# リストで買い物かごをシミュレート
cart = []

# アイテムを追加
cart.append("apple")
cart.append("milk")
cart.append("bread")
cart.append("apple")         # 重複可能
print(f"Cart: {cart}")

# 数量を確認
print(f"Total items: {len(cart)}")

# 変更 — 最初の apple を「apple (2-pack)」に変更
cart[0] = "apple (2-pack)"
print(f"After update: {cart}")

# 最後のアイテムを削除
removed = cart.pop()
print(f"Removed: {removed}")
print(f"Final cart: {cart}")
▶ 試してみよう

出力:

TEXT
Cart: ['apple', 'milk', 'bread', 'apple']
Total items: 4
After update: ['apple (2-pack)', 'milk', 'bread', 'apple']
Removed: apple
Final cart: ['apple (2-pack)', 'milk', 'bread']

4. ソートと反転

PYTHON
numbers = [3, 1, 4, 1, 5, 9, 2]

# sort() — その場でソート(元のリストを変更)
numbers.sort()
print(numbers)              # [1, 1, 2, 3, 4, 5, 9]

# sort(reverse=True) — 降順
numbers.sort(reverse=True)
print(numbers)              # [9, 5, 4, 3, 2, 1, 1]

# reverse() — 順序を反転
numbers.reverse()
print(numbers)              # [1, 1, 2, 3, 4, 5, 9]

# sorted() — 新しいリストを返し、元のリストは変更しない
numbers = [3, 1, 4, 1, 5]
sorted_nums = sorted(numbers)
print(sorted_nums)          # [1, 1, 3, 4, 5]
print(numbers)              # [3, 1, 4, 1, 5](変更なし)
💡 sort() vs sorted() 元の順序を保持する必要がなければ sort() を使います(より速く、メモリ効率が良い)。元の順序を保持する必要があれば sorted() を使います。


5. リストのスライス

スライスは文字列と同じように機能します:list[start:end:step]

PYTHON
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(nums[2:6])            # [2, 3, 4, 5]
print(nums[:4])             # [0, 1, 2, 3] — 最初の 4 つ
print(nums[6:])             # [6, 7, 8, 9] — 6 から最後まで
print(nums[::2])            # [0, 2, 4, 6, 8] — 1 つおき
print(nums[::-1])           # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] — 反転

スライスは代入もサポートしています——リストのユニークな機能です:

PYTHON
nums = [0, 1, 2, 3, 4, 5]

# スライスを置換
nums[1:4] = [10, 20, 30]
print(nums)                 # [0, 10, 20, 30, 4, 5]

# スライスを削除
nums[1:4] = []
print(nums)                 # [0, 4, 5]

例:スライスを使ったページネーション(難易度 ⭐⭐)

PYTHON
# ページネーション表示 — 1 ページあたり 3 項目
items = ["Item A", "Item B", "Item C", "Item D", "Item E", "Item F", "Item G"]

page_size = 3
total_pages = (len(items) + page_size - 1) // page_size

for page in range(total_pages):
    start = page * page_size
    end = start + page_size
    page_items = items[start:end]
    print(f"Page {page + 1}: {page_items}")
▶ 試してみよう

出力:

TEXT
Page 1: ['Item A', 'Item B', 'Item C']
Page 2: ['Item D', 'Item E', 'Item F']
Page 3: ['Item G']

6. ネストしたリスト

リストの要素自体をリストにすることができます——これをネストしたリスト(または 2D リスト)と呼びます。

PYTHON
# 3x4 の「行列」
matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]

# アクセス:最初に行、次に列
print(matrix[0])        # [1, 2, 3, 4] — 最初の行
print(matrix[1][2])     # 7 — 2 行目、3 列目
print(matrix[2][0])     # 9 — 3 行目、1 列目

例:学生スコア表(難易度 ⭐⭐⭐)

PYTHON
# ネストしたリストに学生のスコアを保存
# 各行:[名前, 国語, 数学, 英語]
scores = [
    ["Alice", 85, 92, 78],
    ["Bob", 90, 88, 95],
    ["Charlie", 76, 85, 82],
]

# 各学生の平均を計算して出力
for student in scores:
    name = student[0]
    avg = (student[1] + student[2] + student[3]) / 3
    print(f"{name}: Average {avg:.1f}")

# すべての数学のスコアを出力
print("Math scores:")
for student in scores:
    print(f"  {student[0]}: {student[1]}")
▶ 試してみよう

出力:

TEXT
Alice: Average 85.0
Bob: Average 91.0
Charlie: Average 81.0
Math scores:
  Alice: 85
  Bob: 90
  Charlie: 76

よくあるユースケース


❓ よくある質問

Q リストと文字列の違いは何ですか?
A 主な違いは、リストはミュータブル(変更可能)で、文字列はイミュータブル(変更不可)なことです。リストは異なるデータ型を保持できます。文字列は文字しか保持できません。共通点:どちらもインデックス、スライス、len()in 演算子をサポートします。
⚠️ Q:append()extend() の違いは何ですか? A:append() は引数全体を 1 つの要素として追加します——リストを渡すと、ネストしたリストになります。extend() は引数の各要素を個別に追加します。a = [1,2]; a.append([3,4])[1,2,[3,4]]a.extend([3,4])[1,2,3,4] になります。

Q 存在しない要素を remove() しようとするとどうなりますか?
A ValueError が発生します。最初に in で確認しましょう:if "xxx" in my_list: my_list.remove("xxx")。またはリスト内包表記で新しいフィルタリング済みリストを作成:new_list = [x for x in my_list if x != "xxx"](次のレッスンで学びます)。

📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐):好きな映画 5 つのリストを作成してください。append() で新しいものを追加、pop() で最後のものを削除、sort() でアルファベット順にソートし、リストの長さを出力してください。

  2. 中級(難易度 ⭐⭐)numbers = [23, 45, 12, 67, 34, 89, 5, 18] として、最大値、最小値、合計、平均を求めて出力してください。ヒントmax()min()sum()len() などの組み込み関数を使用。

  3. 挑戦(難易度 ⭐⭐⭐):「To-Do リストマネージャー」を書いてください。リストでタスクを保存します。以下をサポート:add:Buy milkdone:2(番号で削除)、list(すべて表示)。while True で継続的にコマンドを受け付け、exit で終了します。ヒントsplit(":") でコマンドを解析。

100%