メインコンテンツへスキップ
Lesson8 / 8

演習:リストの総合問題

目次

1. このレッスンで学ぶこと

  • モジュール6で学んだリスト操作の総合復習
  • リストの基本操作から応用まで
  • 実践的なリスト処理パターン
  • 多次元リストの活用

2. なぜ演習が必要なのか?

リストはPythonで最も頻繁に使うデータ構造です。様々なパターンを練習することで、実務で使える技術が身につきます。

このレッスンでは、以下のトピックを総合的に復習します:

  • リストの作成と操作
  • インデックスとスライス
  • 要素の追加・削除
  • リストメソッド
  • リスト内包表記
  • 多次元リスト

💡 豆知識: リスト操作はデータ分析、Web開発、ゲーム開発など、あらゆる分野で使われます。これらの演習をマスターすれば、実践的なプログラムが書けるようになります。


3. 基礎演習

演習1: リストの基本操作 ⭐☆☆

空のリストを作り、1から5までの数値を順番に追加してください。その後、リストの長さと全要素を表示してください。

💡 ヒント

append()を使って1つずつ追加します。

✅ 解答例
Python
numbers = []

for i in range(1, 6):
    numbers.append(i)

print(f"リスト: {numbers}")
print(f"長さ: {len(numbers)}")

実行結果:

リスト: [1, 2, 3, 4, 5]
長さ: 5

演習2: スライスの活用 ⭐☆☆

リスト [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] から、以下を取り出してください:

  1. 最初の3個
  2. 最後の3個
  3. 偶数インデックスの要素
💡 ヒント

スライスを使います。

✅ 解答例
Python
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

first_3 = numbers[:3]
last_3 = numbers[-3:]
even_index = numbers[::2]

print(f"最初の3個: {first_3}")
print(f"最後の3個: {last_3}")
print(f"偶数インデックス: {even_index}")

実行結果:

最初の3個: [0, 1, 2]
最後の3個: [7, 8, 9]
偶数インデックス: [0, 2, 4, 6, 8]

演習3: 要素の削除 ⭐☆☆

リスト ["A", "B", "C", "D", "E"] から"C"を削除し、結果を表示してください。

💡 ヒント

remove()を使います。

✅ 解答例
Python
items = ["A", "B", "C", "D", "E"]
print(f"削除前: {items}")

items.remove("C")
print(f"削除後: {items}")

実行結果:

削除前: ['A', 'B', 'C', 'D', 'E']
削除後: ['A', 'B', 'D', 'E']

4. 中級演習

演習4: リストのソートと統計 ⭐⭐☆

リスト [34, 78, 23, 91, 45, 67, 12] について、以下を求めてください:

  1. 昇順にソート
  2. 最大値
  3. 最小値
  4. 平均値
💡 ヒント

sorted(), max(), min(), sum()を使います。

✅ 解答例
Python
numbers = [34, 78, 23, 91, 45, 67, 12]

sorted_numbers = sorted(numbers)
max_value = max(numbers)
min_value = min(numbers)
average = sum(numbers) / len(numbers)

print(f"元のリスト: {numbers}")
print(f"ソート済み: {sorted_numbers}")
print(f"最大値: {max_value}")
print(f"最小値: {min_value}")
print(f"平均値: {average:.2f}")

実行結果:

元のリスト: [34, 78, 23, 91, 45, 67, 12]
ソート済み: [12, 23, 34, 45, 67, 78, 91]
最大値: 91
最小値: 12
平均値: 50.00

演習5: リスト内包表記 ⭐⭐☆

1から20までの数のうち、3の倍数だけを含むリストをリスト内包表記で作成してください。

💡 ヒント

if文で3の倍数をフィルタします。

✅ 解答例
Python
multiples_of_3 = [x for x in range(1, 21) if x % 3 == 0]
print(f"3の倍数: {multiples_of_3}")

実行結果:

3の倍数: [3, 6, 9, 12, 15, 18]

演習6: 重複の削除 ⭐⭐☆

リスト [1, 2, 2, 3, 4, 4, 4, 5, 1, 3] から重複を削除し、元の順序を保ったリストを作成してください。

💡 ヒント

見たことのある値を記録しながら新しいリストを作ります。

✅ 解答例
Python
numbers = [1, 2, 2, 3, 4, 4, 4, 5, 1, 3]
unique = []

for num in numbers:
    if num not in unique:
        unique.append(num)

print(f"元のリスト: {numbers}")
print(f"重複削除後: {unique}")

実行結果:

元のリスト: [1, 2, 2, 3, 4, 4, 4, 5, 1, 3]
重複削除後: [1, 2, 3, 4, 5]

5. 応用演習

演習7: 2つのリストの共通要素 ⭐⭐⭐

2つのリスト [1, 2, 3, 4, 5][3, 4, 5, 6, 7] の共通要素を見つけてください。

💡 ヒント

両方のリストに含まれる要素を探します。

✅ 解答例
Python
list1 = [1, 2, 3, 4, 5]
list2 = [3, 4, 5, 6, 7]

common = [x for x in list1 if x in list2]

print(f"リスト1: {list1}")
print(f"リスト2: {list2}")
print(f"共通要素: {common}")

# または集合を使う
common_set = list(set(list1) & set(list2))
print(f"集合使用: {sorted(common_set)}")

実行結果:

リスト1: [1, 2, 3, 4, 5]
リスト2: [3, 4, 5, 6, 7]
共通要素: [3, 4, 5]
集合使用: [3, 4, 5]

演習8: 成績の集計 ⭐⭐⭐

生徒の成績リスト [85, 92, 45, 78, 95, 60, 88, 55, 90, 70] について:

  1. 60点以上の人数
  2. 80点以上の人数
  3. 最高点と最低点
  4. トップ3の点数
💡 ヒント

フィルタとソートを組み合わせます。

✅ 解答例
Python
scores = [85, 92, 45, 78, 95, 60, 88, 55, 90, 70]

# 合格者(60点以上)
passed = [s for s in scores if s >= 60]
passed_count = len(passed)

# 優秀者(80点以上)
excellent = [s for s in scores if s >= 80]
excellent_count = len(excellent)

# 最高点と最低点
max_score = max(scores)
min_score = min(scores)

# トップ3
sorted_scores = sorted(scores, reverse=True)
top3 = sorted_scores[:3]

print("=== 成績集計 ===")
print(f"総人数: {len(scores)}人")
print(f"合格者(60点以上): {passed_count}人")
print(f"優秀者(80点以上): {excellent_count}人")
print(f"最高点: {max_score}点")
print(f"最低点: {min_score}点")
print(f"トップ3: {top3}")

実行結果:

=== 成績集計 ===
総人数: 10人
合格者(60点以上): 8人
優秀者(80点以上): 5人
最高点: 95点
最低点: 45点
トップ3: [95, 92, 90]

演習9: リストの回転 ⭐⭐⭐

リスト [1, 2, 3, 4, 5] を右に2つ回転してください(結果: [4, 5, 1, 2, 3])。

💡 ヒント

スライスを使って分割し、順序を入れ替えます。

✅ 解答例
Python
numbers = [1, 2, 3, 4, 5]
n = 2  # 回転数

rotated = numbers[-n:] + numbers[:-n]

print(f"元のリスト: {numbers}")
print(f"{n}つ右回転: {rotated}")

# 左回転
left_rotated = numbers[n:] + numbers[:n]
print(f"{n}つ左回転: {left_rotated}")

実行結果:

元のリスト: [1, 2, 3, 4, 5]
2つ右回転: [4, 5, 1, 2, 3]
2つ左回転: [3, 4, 5, 1, 2]

演習10: 平坦化 ⭐⭐⭐

ネストしたリスト [[1, 2, 3], [4, 5], [6, 7, 8, 9]] を1次元リストに平坦化してください。

💡 ヒント

ネストしたループまたはリスト内包表記を使います。

✅ 解答例
Python
nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]

# 方法1: ネストしたループ
flat = []
for sublist in nested:
    for item in sublist:
        flat.append(item)

print(f"元のリスト: {nested}")
print(f"平坦化: {flat}")

# 方法2: リスト内包表記
flat2 = [item for sublist in nested for item in sublist]
print(f"内包表記: {flat2}")

実行結果:

元のリスト: [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
平坦化: [1, 2, 3, 4, 5, 6, 7, 8, 9]
内包表記: [1, 2, 3, 4, 5, 6, 7, 8, 9]

演習11: 行列の転置 ⭐⭐⭐

3×3の行列を転置(行と列を入れ替え)してください。

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
💡 ヒント

i行j列の要素をj行i列に移動します。

✅ 解答例
Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 転置
transposed = [[matrix[j][i] for j in range(len(matrix))] for i in range(len(matrix[0]))]

print("元の行列:")
for row in matrix:
    print(row)

print("\n転置行列:")
for row in transposed:
    print(row)

実行結果:

元の行列:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

転置行列:
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]

演習12: ランレングス符号化 ⭐⭐⭐

リスト [1, 1, 1, 2, 2, 3, 3, 3, 3, 1] をランレングス符号化してください。 結果: [(1, 3), (2, 2), (3, 4), (1, 1)](値, 連続回数)

💡 ヒント

連続する同じ値をカウントします。

✅ 解答例
Python
data = [1, 1, 1, 2, 2, 3, 3, 3, 3, 1]

encoded = []
if data:
    current_value = data[0]
    count = 1

    for i in range(1, len(data)):
        if data[i] == current_value:
            count += 1
        else:
            encoded.append((current_value, count))
            current_value = data[i]
            count = 1

    # 最後の要素を追加
    encoded.append((current_value, count))

print(f"元のデータ: {data}")
print(f"符号化: {encoded}")

# デコード
decoded = []
for value, count in encoded:
    decoded.extend([value] * count)
print(f"復号化: {decoded}")

実行結果:

元のデータ: [1, 1, 1, 2, 2, 3, 3, 3, 3, 1]
符号化: [(1, 3), (2, 2), (3, 4), (1, 1)]
復号化: [1, 1, 1, 2, 2, 3, 3, 3, 3, 1]

演習13: 移動平均 ⭐⭐⭐

リスト [10, 20, 30, 40, 50, 60, 70] の3点移動平均を計算してください。

💡 ヒント

3つずつ取り出して平均を計算します。

✅ 解答例
Python
data = [10, 20, 30, 40, 50, 60, 70]
window_size = 3

moving_avg = []
for i in range(len(data) - window_size + 1):
    window = data[i:i + window_size]
    avg = sum(window) / window_size
    moving_avg.append(avg)

print(f"元のデータ: {data}")
print(f"3点移動平均: {moving_avg}")

実行結果:

元のデータ: [10, 20, 30, 40, 50, 60, 70]
3点移動平均: [20.0, 30.0, 40.0, 50.0, 60.0]

演習14: 二分探索 ⭐⭐⭐

ソート済みリスト [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] から値7を二分探索で見つけてください。

💡 ヒント

中央値と比較して範囲を半分ずつ絞ります。

✅ 解答例
Python
def binary_search(arr, target):
    left = 0
    right = len(arr) - 1

    while left <= right:
        mid = (left + right) // 2

        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1

    return -1

numbers = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
target = 7

index = binary_search(numbers, target)

if index != -1:
    print(f"{target}はインデックス{index}にあります")
else:
    print(f"{target}は見つかりませんでした")

実行結果:

7はインデックス3にあります

演習15: フィルタと変換の組み合わせ ⭐⭐⭐

リスト [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] について:

  1. 偶数だけを抽出
  2. それぞれを2乗
  3. 結果をリスト内包表記で1行で書く
💡 ヒント

フィルタと変換を1つのリスト内包表記にまとめます。

✅ 解答例
Python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result = [x ** 2 for x in numbers if x % 2 == 0]

print(f"元のリスト: {numbers}")
print(f"偶数の2乗: {result}")

実行結果:

元のリスト: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
偶数の2乗: [4, 16, 36, 64, 100]

6. まとめ

このレッスンでは、リスト操作を演習で統合して確認しました。

  • 基本操作、アクセス、スライス、追加削除、メソッドを組み合わせて実装できました。
  • 要件に応じて適切なリスト操作を選ぶ判断力を確認しました。
  • ネスト構造や条件付き処理を使った実践的な問題に対応できました。
  • 途中結果を出力して状態を確認するデバッグ手順を実践しました。
  • 複雑な処理を分解して段階的に作る進め方を身につけました。