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

多次元リスト(2次元配列)

目次

このレッスンで学ぶこと

  • 多次元リストとは何か
  • 2次元リストの作成と操作
  • 行列のような表データの扱い方
  • ネストしたリストの注意点

多次元リストとは

多次元リストは、リストの中にリストが入っている構造です。最も一般的な2次元リストは、Excelの表やゲームボード、行列など、行と列を持つデータを表現するのに使われます。

項目説明
基本形式[[要素1, 要素2], [要素3, 要素4]]
アクセス方法リスト[行][列]
行の取得リスト[行番号]
列の取得[row[列番号] for row in リスト]
用途表形式データ、行列、ゲームボード

主な特徴:

  • リストのリストとして実装される(ネストされたリスト)
  • 行と列で2次元のデータを表現できる
  • 3次元以上のリストも可能(ただし複雑になる)
  • 各行の要素数が異なっていても良い

簡単なコード例:

Python
# 3×3の行列
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# アクセス
print(f"2行2列: {matrix[1][1]}")  # 5

# 1行目全体
print(f"1行目: {matrix[0]}")  # [1, 2, 3]

# 2列目全体
column = [row[1] for row in matrix]
print(f"2列目: {column}")  # [2, 5, 8]

# 全要素を表示
for row in matrix:
    print(row)

実行結果:

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

なぜ多次元リストが必要なのか?

表形式のデータや行列を扱うとき、多次元リストが便利です。

Python
# 3人の生徒の3科目の成績
scores = [
    [85, 90, 78],  # 生徒1
    [92, 88, 95],  # 生徒2
    [76, 82, 89]   # 生徒3
]

# 生徒2の数学の点数(2行目、2列目)
print(f"生徒2の数学: {scores[1][1]}点")

実行結果:

生徒2の数学: 88点

多次元リストを使うことで、表形式のデータを扱えます。

💡 豆知識: 2次元リストは「リストのリスト」として実装されます。Excelのセルや碁盤の目、座標平面などを表現するのに使われます。


2次元リストの基本

2次元リストの作成

機能: リストの各要素がリストになっている構造を作ります。

書き方:

Python
リスト = [
    [要素1, 要素2, ...],
    [要素1, 要素2, ...],
    ...
]

用途: 表データ、行列、座標データ、ゲームボード

注意点:

  • 各行の要素数は揃えなくてもよい
  • アクセスは[行][列]の順
  • コピーに注意が必要
Python
# 3×3の行列
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matrix)
print(f"行数: {len(matrix)}")
print(f"列数: {len(matrix[0])}")

実行結果:

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

要素へのアクセス

機能: [行インデックス][列インデックス]で要素にアクセスします。

書き方:

Python
= リスト[][]
リスト[][] = 新しい値

用途: 特定セルの取得・変更、データの更新

注意点:

  • インデックスは0から始まる
  • 範囲外アクセスはエラー
Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 要素の取得
print(f"1行1列: {matrix[0][0]}")
print(f"2行2列: {matrix[1][1]}")
print(f"3行3列: {matrix[2][2]}")

# 要素の変更
matrix[1][1] = 50
print(f"変更後: {matrix}")

実行結果:

1行1列: 1
2行2列: 5
3行3列: 9
変更後: [[1, 2, 3], [4, 50, 6], [7, 8, 9]]

2次元リストの作成方法

直接作成

Python
# 成績表
scores = [
    [85, 90, 78],
    [92, 88, 95],
    [76, 82, 89]
]

print("=== 成績表 ===")
for i, student in enumerate(scores, 1):
    print(f"生徒{i}: {student}")

実行結果:

=== 成績表 ===
生徒1: [85, 90, 78]
生徒2: [92, 88, 95]
生徒3: [76, 82, 89]

ループで作成

Python
# 5×5の行列を作成
rows = 5
cols = 5

matrix = []
for i in range(rows):
    row = []
    for j in range(cols):
        row.append(i * cols + j + 1)
    matrix.append(row)

print("=== 5×5行列 ===")
for row in matrix:
    print(row)

実行結果:

=== 5×5行列 ===
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[11, 12, 13, 14, 15]
[16, 17, 18, 19, 20]
[21, 22, 23, 24, 25]

リスト内包表記で作成

Python
# 3×3のゼロ行列
zeros = [[0 for j in range(3)] for i in range(3)]
print("ゼロ行列:")
for row in zeros:
    print(row)

# 掛け算の九九表
kuku = [[i * j for j in range(1, 10)] for i in range(1, 10)]
print("\n九九表(最初の3行):")
for row in kuku[:3]:
    print(row)

実行結果:

ゼロ行列:
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]

九九表(最初の3行):
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 4, 6, 8, 10, 12, 14, 16, 18]
[3, 6, 9, 12, 15, 18, 21, 24, 27]

2次元リストの操作

行の取得

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 特定の行を取得
row1 = matrix[0]
row2 = matrix[1]

print(f"1行目: {row1}")
print(f"2行目: {row2}")

実行結果:

1行目: [1, 2, 3]
2行目: [4, 5, 6]

列の取得

機能: 特定の列の全要素を取得します。

書き方:

Python
= [[列番号] forin リスト]

用途: 列データの集計、縦方向の計算

注意点: リスト内包表記を使う

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 2列目を取得(インデックス1)
col2 = [row[1] for row in matrix]
print(f"2列目: {col2}")

# 全列を取得
for i in range(3):
    col = [row[i] for row in matrix]
    print(f"{i+1}列目: {col}")

実行結果:

2列目: [2, 5, 8]
1列目: [1, 4, 7]
2列目: [2, 5, 8]
3列目: [3, 6, 9]

全要素の走査

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 全要素を表示
print("=== 全要素 ===")
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(f"[{i}][{j}] = {matrix[i][j]}")

# より簡潔に
print("\n=== 値のみ ===")
for row in matrix:
    for value in row:
        print(value, end=" ")
print()

実行結果:

=== 全要素 ===
[0][0] = 1
[0][1] = 2
[0][2] = 3
[1][0] = 4
[1][1] = 5
[1][2] = 6
[2][0] = 7
[2][1] = 8
[2][2] = 9

=== 値のみ ===
1 2 3 4 5 6 7 8 9

具体例

例1: 座席表

Python
# 座席の状態(0:空席、1:予約済み)
seats = [
    [0, 1, 0, 1],
    [1, 0, 0, 0],
    [0, 0, 1, 1]
]

print("=== 座席状況 ===")
for i, row in enumerate(seats, 1):
    print(f"{i}行目: ", end="")
    for j, seat in enumerate(row, 1):
        status = "×" if seat == 1 else "○"
        print(f"{status}", end=" ")
    print()

# 空席数
empty_count = sum(row.count(0) for row in seats)
print(f"\n空席数: {empty_count}")

実行結果:

=== 座席状況 ===
1行目: ○ × ○ ×
2行目: × ○ ○ ○
3行目: ○ ○ × ×

空席数: 6

例2: 成績表

Python
# 生徒の成績(国語、数学、英語)
scores = [
    [85, 90, 78],
    [92, 88, 95],
    [76, 82, 89]
]

students = ["田中", "佐藤", "鈴木"]
subjects = ["国語", "数学", "英語"]

print("=== 成績表 ===")
print(f"{'':6}", end="")
for subject in subjects:
    print(f"{subject:6}", end="")
print("  平均")

for i, (student, score_list) in enumerate(zip(students, scores)):
    avg = sum(score_list) / len(score_list)
    print(f"{student:6}", end="")
    for score in score_list:
        print(f"{score:6}", end="")
    print(f"{avg:6.1f}")

実行結果:

=== 成績表 ===
      国語    数学    英語    平均
田中      85    90    78  84.3
佐藤      92    88    95  91.7
鈴木      76    82    89  82.3

例3: ビンゴカード

Python
import random

# 5×5のビンゴカード
bingo = [[0 for j in range(5)] for i in range(5)]

# 数字を配置
for i in range(5):
    for j in range(5):
        if i == 2 and j == 2:
            bingo[i][j] = 0  # 中央はFREE
        else:
            # 各列で範囲を決める
            min_val = i * 15 + 1
            max_val = min_val + 14
            bingo[i][j] = random.randint(min_val, max_val)

# 表示
print("=== ビンゴカード ===")
headers = ["B", "I", "N", "G", "O"]
print("  ", end="")
for h in headers:
    print(f"{h:4}", end="")
print()

for i, row in enumerate(bingo):
    print(f"{i+1} ", end="")
    for value in row:
        if value == 0:
            print("FREE", end="")
        else:
            print(f"{value:4}", end="")
    print()

例4: マス目の移動

Python
# 3×3のマス目
board = [[0 for j in range(3)] for i in range(3)]

# 現在位置
x, y = 1, 1
board[y][x] = 1

def show_board():
    print("=== ボード ===")
    for row in board:
        for cell in row:
            print("●" if cell == 1 else "・", end=" ")
        print()

show_board()

# 右に移動
board[y][x] = 0
x += 1
board[y][x] = 1

print("\n右に移動:")
show_board()

実行結果:

=== ボード ===
・ ・ ・
・ ● ・
・ ・ ・

右に移動:
=== ボード ===
・ ・ ・
・ ・ ●
・ ・ ・

例5: 行列の演算

Python
# 行列の加算
matrix_a = [
    [1, 2, 3],
    [4, 5, 6]
]

matrix_b = [
    [10, 20, 30],
    [40, 50, 60]
]

# 加算結果
result = []
for i in range(len(matrix_a)):
    row = []
    for j in range(len(matrix_a[0])):
        row.append(matrix_a[i][j] + matrix_b[i][j])
    result.append(row)

print("A + B =")
for row in result:
    print(row)

実行結果:

A + B =
[11, 22, 33]
[44, 55, 66]

例6: 画像データ(グレースケール)

Python
# 5×5のグレースケール画像(0:黒、255:白)
image = [
    [0, 0, 255, 0, 0],
    [0, 255, 0, 255, 0],
    [255, 0, 0, 0, 255],
    [0, 255, 0, 255, 0],
    [0, 0, 255, 0, 0]
]

print("=== 画像表示 ===")
for row in image:
    for pixel in row:
        print("■" if pixel == 0 else "□", end="")
    print()

実行結果:

=== 画像表示 ===
■■□■■
■□■□■
□■■■□
■□■□■
■■□■■

よくある間違い

間違い1: 間違ったコピー

Python
# 危険: 同じリストへの参照が作られる
rows = 3
cols = 3
matrix = [[0] * cols] * rows

matrix[0][0] = 1
print("間違ったコピー:")
for row in matrix:
    print(row)

# 正しい
matrix = [[0 for j in range(cols)] for i in range(rows)]
matrix[0][0] = 1
print("\n正しいコピー:")
for row in matrix:
    print(row)

実行結果:

間違ったコピー:
[1, 0, 0]
[1, 0, 0]
[1, 0, 0]

正しいコピー:
[1, 0, 0]
[0, 0, 0]
[0, 0, 0]

間違い2: インデックスの順序

Python
matrix = [
    [1, 2, 3],
    [4, 5, 6]
]

# 間違い: [列][行]
# print(matrix[1][3])  # エラー

# 正しい: [行][列]
print(f"2行2列: {matrix[1][1]}")

実行結果:

2行2列: 5

間違い3: 不均一な行

Python
# 各行の長さが異なる
matrix = [
    [1, 2, 3],
    [4, 5],
    [6, 7, 8, 9]
]

# 安全なアクセス
for i, row in enumerate(matrix):
    print(f"{i}行目({len(row)}要素): {row}")

実行結果:

0行目(3要素): [1, 2, 3]
1行目(2要素): [4, 5]
2行目(4要素): [6, 7, 8, 9]

練習問題

問題1(基礎)⭐☆☆

3×3のゼロ行列を作成してください。

💡 ヒント

リスト内包表記を使います。

✅ 解答例
Python
matrix = [[0 for j in range(3)] for i in range(3)]

for row in matrix:
    print(row)

実行結果:

[0, 0, 0]
[0, 0, 0]
[0, 0, 0]

問題2(基礎)⭐☆☆

以下の行列の2行目の合計を計算してください。

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

matrix[1]で2行目を取得し、sum()で合計します。

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

row2_sum = sum(matrix[1])
print(f"2行目の合計: {row2_sum}")

実行結果:

2行目の合計: 15

問題3(応用)⭐⭐☆

3×3の単位行列を作成してください(対角線が1、それ以外が0)。

💡 ヒント

i == j のときだけ1にします。

✅ 解答例
Python
identity = [[1 if i == j else 0 for j in range(3)] for i in range(3)]

for row in identity:
    print(row)

実行結果:

[1, 0, 0]
[0, 1, 0]
[0, 0, 1]

まとめ

このレッスンでは、多次元リストの構造と操作方法を学びました。

  • 多次元リストは「リストの中にリスト」を持つ構造で表を表現できます。
  • 二重インデックスで行と列を指定して要素へアクセスできます。
  • ネストしたループで全要素を走査し、集計や変換を実装できます。
  • 初期化時の参照共有など、多次元特有の落とし穴を理解しました。
  • データ構造を図で把握してから実装することでミスを減らせます。