【最大80% OFF】Kindle本クリスマスセール開催中(12/26まで)

【Python】2次元配列の入門(覚えておきたい操作)

9 min

こんにちは、ナミレリです。今回の記事ではPythonの配列の中でも2次元配列に特化して解説していきます。「2次元配列」と聞くと少し難しく感じるかもしれませんが、2次元配列は身近な存在で、例えばスプレッドシートの表、カレンダー、ゲームのマップ、成績表など、行と列で整理されたデータと考えるとわかりやすいと思います。

この記事はこんな人にオススメ

  • Pythonでの配列の扱い方を学びたい方
  • 2次元配列って何?と基本的な概念から知りたい方
  • 表形式のデータを扱いたい方
  • スプレッドシートやエクセルのようなデータ操作をPythonで実現したい方
  • 迷路探索やグリッド操作など、よく出題される問題に挑戦したい方
  • Pythonを使ったデータ処理や行列演算の基礎を理解したい方
  • NumPyなどのライブラリを学び始めた方
  • リストの基礎的な操作方法を具体的なコードで学びたい方
  • カレンダーやゲームマップなど、日常に役立つ例を探している方
この記事のMac環境
Parallels Desktop 20 for Macの無料トライアル もありますので、ぜひダウンロードして試してみてください。M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。

2次元配列とは

2次元配列は、行と列でデータを整理して扱える便利なデータ構造です。Pythonでは標準ライブラリのリストを使うことで2次元配列を扱うことができます。配列の高度な操作をしたい場合はNumpyライブラリを利用すると簡単に操作することもできます。

2次元配列を簡単に言うと、「表(テーブル)形式のデータ」のようなものです。行(横方向)と列(縦方向)で構成され、例えば下のようなイメージです。

2次元配列のイメージ
2次元配列のイメージ

Pythonのコードでイメージすると、下のようになります。


[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12]
]

2次元配列はどんな時に使うのか

このような行と列のデータ構造である2次元配列は、どんな時に使うのでしょうか?日常的に使われる「表形式のデータ」を表現したり操作する際に使うと便利です。

いくつかの例を紹介します。

例えば、成績などをスプレッドシートなど表のようにデータを管理、操作する。


# 2次元配列の成績表
grades = [
    ["Tanaka", 85, 90, 78],  # 名前, 数学, 英語, 理科
    ["Sato", 92, 88, 84],
    ["Yamada", 75, 70, 80]
]

例えば、画像データのRGBを表のようにデータを管理、操作する。


# 2次元配列で白黒画像を表現
image = [
    [0, 255, 255],  # 0は黒、255は白
    [255, 0, 255],
    [255, 255, 0]
]

 例えば、マップやゲームの盤面を表のようにデータを管理、操作する。


# ゲームの盤面
board = [
    [0, 1, -1],  # 0は空、1は数字、-1は地雷
    [0, 1, 1],
    [-1, 0, 0]
]

例えば、X, Yの座標データを表のようにデータを管理、操作する。


# 座標リスト
coordinates = [
    [0, 0],  # (X, Y)
    [10, 5],
    [15, 10]
]

例えば、温度などの時系列のデータを表のようにデータを管理、操作する。


# 各地点の温度データ(時間 × 地点)
data = [
    [22.5, 23.0, 21.8],  # 時刻1
    [22.7, 23.2, 21.9],  # 時刻2
    [23.0, 23.5, 22.0]   # 時刻3
]

例えば、パズルや数独を表のようにデータを管理、操作する。


# 数独の盤面
board = [
    [5, 3, 0, 0, 7, 0, 0, 0, 0],
    [6, 0, 0, 1, 9, 5, 0, 0, 0],
    [0, 9, 8, 0, 0, 0, 0, 6, 0],
    # ...
]

例えば、データサイエンスで使うデータを表のようにデータを管理、操作する。


# 機械学習用データ(特徴量 × ラベル)
data = [
    [1.2, 3.4, 0],  # 特徴量1, 特徴量2, ラベル
    [2.1, 1.8, 1],
    [0.5, 2.3, 0]
]

これらの例以外にも、行と列の表形式で整理し利用するデータは、2次元配列を活用することができます。

では、実際に2次元配列の操作をしていきましょう。

2次元配列の作成

まずは、2次元配列の値を指定して2次元配列を作成する方法です。もっとも基本的な2次元配列の指定方法です。


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

print(array)
# 出力: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(array[0][0])
# 出力:1

print(array[1][1])
# 出力:5

上記の2次元配列を、forループを使って作成することもできます。


rows, cols = 3, 3
array = [[cols * i + j + 1 for j in range(cols)] for i in range(rows)]

print(array)
# 出力: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(array[0][0])
# 出力:1

print(array[1][1])
# 出力:5

forループを使って、自動的に値を埋めた2次元配列を作成することもできます。


# 3行4列の0で埋められた配列を作成
rows, cols = 3, 4
array = [[0 for _ in range(cols)] for _ in range(rows)]

print(array)
# 出力: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

print(array[0][0])
# 出力:0

print(array[1][1])
# 出力:0

要素へのアクセス

次に、2次元配列の各要素にどのようにアクセスするかを説明します。基本的には行番号と列番号を使って要素にアクセスします。

2次元配列の各要素にアクセスする
2次元配列の各要素にアクセスする

1行目2列目の要素にアクセスする場合は、array[0][1]でアクセスします。

下の2次元配列に対して操作します


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

# 1行目2列目の要素(インデックス0,1)
print(array[0][1])

1つ1つの各要素ではなく、特定の行や列を取得することもできます。

1行目を取得するには、array[0]で、2行目を取得するにはarray[1]です。

特定の行を取得してみます。

下の2次元配列に対して操作します


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

# 1行目を取得
row = array[0]
print(row)
# 出力: [1, 2, 3]

# 2行目を取得
print(array[1])
# 出力: [4, 5, 6]

次に、特定の列を取得してみます。列はforループやリスト内包表記で取得するので少し複雑です。

列を取得する方法(forループ)

下の2次元配列に対して操作します


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

col = []
for row in array:
    col.append(row[1])  # 各行の2列目を追加
print(col)
# [2, 5, 8]

慣れてくると、下の様にリスト内包表記で記載すると簡単です。

列を取得方法(リスト内包表記)

下の2次元配列に対して操作します


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

# 2列目を取得する場合
col = [row[1] for row in array]  # 2列目のすべての要素
print(col)
# 出力: [2, 5, 8]

上記のように、2次元配列の特定の列にアクセスするには、各行の「同じ列番号の要素」を取得します。

例えば、2列目(列番号1)を取り出す場合は、すべての行に対して、同じ列番号の要素を取得すると、結果として2列目の要素のリストが得られます。


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

• 0行目の1列目 → array[0][1](値:2)

• 1行目の1列目 → array[1][1](値:5)

• 2行目の1列目 → array[2][1](値:8)

すべての行に対して、同じ列番号の要素を取得すると、列全体を取得できる。

要素の変更

続いて、要素の値を変更する方法を説明します。

まずは指定した単一の要素を変更してみます。

下の2次元配列に対して操作します


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

# 2行目3列目を99に変更
array[1][2] = 99

print(array)
# 出力: [[1, 2, 3], [4, 5, 99], [7, 8, 9]]

特定の行や列を一括変更することもできます。直接値を指定する方法とforループを使う方法を紹介します。

行の値を一括変更する方法(直接値を指定)

1行目をすべて10に変更する例です。


# 1行目をすべて10に変更
array[0] = [10, 10, 10]

行の値を一括変更する方法(forループ)

1行目をすべて100に変更する例です。


# 1行目をすべて100に変更
for j in range(len(array[0])):
    array[0][j] = 100

列の値を一括変更する方法(forループ)

2列目をすべて20に変更する例です。


# 2列目をすべて20に変更
for row in array:
    row[1] = 20

配列のサイズ変更(行の追加や削除、列の追加や削除)

次は配列に行を追加・削除したり、列を追加・削除する方法です。

下の2次元配列に対して操作します


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

行の末尾に新しい行を追加します。


# 末尾に新しい行を追加
array.append([10, 11, 12])

print(array)
# 出力: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

末尾ではなく、指定した行に追加したい場合は、insertを使って特定の位置に行を追加できます。

下のように2行目に行を追加してみましょう。


# 2行目(インデックス1)に新しい行を挿入
new_row = [100, 100, 100]
array.insert(1, new_row)

print(array)
# 出力: [[1, 2, 3], [100, 100, 100], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

続いて列を追加します。

下の2次元配列に対して操作します


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

一番右に列を追加します。つまりはすべての行の末尾に新しい値を追加することで実現します。


for row in array:
    row.append(0)

print(array)
# 出力: [[1, 2, 3, 0], [4, 5, 6, 0], [7, 8, 9, 0]]

指定した箇所に新しい列を追加する場合は、ループやリスト内包表記を使って実現します。


# 3列目(インデックス2)に新しい列 [100, 100, 100] を挿入
new_column = [100, 100, 100]
for i in range(len(array)):
    array[i].insert(2, new_column[i])

print(array)
出力: [[1, 2, 100, 3, 0], [4, 5, 100, 6, 0], [7, 8, 100, 9, 0]]

続いて、行と列の削除です。

2行目を削除します。


# 2行目を削除
del array[1]

2列目を削除します。


import copy
copy_array = copy.deepcopy(array)

ループ処理のまとめ

行単位のループ処理

下のように、行単位でループします。


# 行単位でループ処理
for row in array:
    print(row)

行単位のループの応用として、各行の合計を計算する場合は下のようになります。


for row in array:
    print(sum(row))

列単位のループ処理

列を処理する場合、各行の同じインデックスの要素をまとめて処理します。zip(*array)を使うと便利です。


# 列単位でループ処理
for col in zip(*array):
    print(col)

列単位のループの応用として、各列の合計を計算する場合は下のようになります。


for col in zip(*array):
    print(sum(col))

要素単位のループ処理

2次元配列のすべての要素を1つずつ処理する場合は、ネストしたループを使います。


for row in array:
    for element in row:
        print(element)

インデックスを利用したループ処理

インデックス(行番号と列番号)を使いたい場合は、range()を使ったループを使います。


# インデックスを利用して要素を出力
for i in range(len(array)):  # 行インデックス
    for j in range(len(array[i])):  # 列インデックス
        print(f"array[{i}][{j}] = {array[i][j]}")

2次元配列のループ処理のまとめ

これまでに紹介したループ処理をまとめます。

処理単位方法
行単位のループfor row in array
列単位のループfor col in zip(*array)
要素単位のループ入れ子のループで for element in row
インテックスを利用したループfor i in range(len(array))

2次元配列の並べ替え

numpyを使わずに2次元配列を行単位や列単位でソートする方法を紹介します。

行単位でソート

下の2次元配列に対して操作します


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

2次元配列の各行をソートする方法です。


# 各行をソート
for row in array:
    row.sort()

print(array)
# 出力: [[1, 2, 3], [5, 7, 9], [4, 6, 8]]

列単位でソート

下の2次元配列に対して操作します


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

列単位でソートするには、列を1つずつ抽出してソートして再び2次元配列に戻します。


# 行数、列数
rows = len(array)
cols = len(array[0])

# 列ごとに抽出、ソート、再配置
for col_idx in range(cols):
    column = [array[row_idx][col_idx] for row_idx in range(rows)]  # 列を取得
    column.sort()  # 列をソート
    for row_idx in range(rows):
        array[row_idx][col_idx] = column[row_idx]  # ソートされた列を再配置

print(array)
# 出力:[[3, 1, 2], [6, 5, 4], [9, 8, 7]]

import pprint
pprint.pprint(array, width=15)
# [[3, 1, 2],
#  [6, 5, 4],
#  [9, 8, 7]]

ちなみに、行数はlen(array)で取得し、列数はlen(array[0])で取得します。


rows = len(array)  # 行数
cols = len(array[0])  # 列数

all()を使った操作方法

all()は、配列のすべての要素が条件を満たしているかをチェックすることができます。

各行ごとにチェック:all()

各行ごとにすべての要素が条件を満たしているかをチェックします。


array = [
    [2, 4, 6],
    [8, 10, 12],
    [14, 16, 18]
]

# 各行がすべて偶数かチェック
for row in array:
    if all(element % 2 == 0 for element in row):
        print(f"{row} はすべて偶数です")

# 出力
# [2, 4, 6] はすべて偶数です
# [8, 10, 12] はすべて偶数です
# [14, 16, 18] はすべて偶数です

配列全体をチェック:all()

配列の全ての要素が条件を満たしているかをチェックします。


# 配列全体がすべて偶数かチェック
if all(all(element % 2 == 0 for element in row) for row in array):
    print("配列全体がすべて偶数です")
else:
    print("配列に奇数が含まれています")
Pythonユーザーにおすすめの本

「自分が書いたコードは、仕事で通用するか不安……」

「動くものは作れる。そこからどう上達すればいい?」

そんな悩みを抱えるあなたに、VTuberサプーがPythonでのコードの書きかたをお教えします! 本書は、コードの見た目の整えかたから、読みやすさ、シンプルさ、安全性……などを意識した「プロ」の知識とテクニックをまとめました。中の人のエンジニア経験から得た知見をもとに解説しているので、実際に現場でちゃんと役立つコードに改善できます。この1冊で、自分の書くコードをワンランクアップさせましょう!

Amazon

VTuberサプーが教える! Python 初心者のコード/プロのコード

おすすめ定番記事

カテゴリー:
関連記事