入れ子のループ:繰り返しの中の繰り返し#
はじめに#
これまでの記事では、「for文」と「while文」という繰り返し処理の方法と、「break文」と「continue文」というループを制御する方法を学びました。
今回は、「入れ子のループ」という技術について学びましょう。入れ子のループとは、ループの中にさらにループを入れることです。例えるなら、「一週間の毎日(外側のループ)、朝・昼・夜と3回食事をする(内側のループ)」といった状況を表現できます。
入れ子のループを使うと、表形式のデータを扱ったり、複雑なパターンを作ったりすることができます。この記事では、基本から応用まで詳しく解説していきます。
入れ子のループの基本#
入れ子のループは、ループの中に別のループを入れることで作成します。外側のループが1回実行されるごとに、内側のループが最初から最後まで実行されます。
基本的な形は次のとおりです。
# 外側のループ
for 外側の変数 in 外側のシーケンス:
# 外側のループの処理
# 内側のループ
for 内側の変数 in 内側のシーケンス:
# 内側のループの処理
# 外側のループの続き
簡単な例で見てみましょう。
# 基本的な入れ子のループ
print("入れ子のループの基本例:")
for i in range(3): # 外側のループ
print(f"外側のループ: i = {i}")
for j in range(2): # 内側のループ
print(f" 内側のループ: j = {j}")
print("外側のループの1回分の終わり")
入れ子のループの基本例:
外側のループ: i = 0
内側のループ: j = 0
内側のループ: j = 1
外側のループの1回分の終わり
外側のループ: i = 1
内側のループ: j = 0
内側のループ: j = 1
外側のループの1回分の終わり
外側のループ: i = 2
内側のループ: j = 0
内側のループ: j = 1
外側のループの1回分の終わり
この例では、外側のループが3回(i=0, 1, 2)、内側のループが各回で2回(j=0, 1)実行されるため、内側のループの処理は合計で3 × 2 = 6回実行されます。
入れ子のwhileループ#
入れ子のループは、for文だけでなくwhile文でも作成できます。また、for文とwhile文を組み合わせることも可能です。
# while文を使った入れ子のループ
print("while文を使った入れ子のループ:")
# 教科書の各章と問題を確認する例
chapter = 1
while chapter <= 3:
print(f"第{chapter}章を勉強中")
problem = 1
while problem <= 2:
print(f" 問題{chapter}-{problem}を解く")
problem += 1
print(f"第{chapter}章を終了")
chapter += 1
while文を使った入れ子のループ:
第1章を勉強中
問題1-1を解く
問題1-2を解く
第1章を終了
第2章を勉強中
問題2-1を解く
問題2-2を解く
第2章を終了
第3章を勉強中
問題3-1を解く
問題3-2を解く
第3章を終了
この例では、for文の場合と同様に、外側のループが1回実行されるごとに、内側のループが最初から最後まで実行されます。
入れ子のループとbreak文#
前回の記事で学んだbreak文は、入れ子のループでも使うことができます。ただし注意が必要なのは、break文は自分が属する「最も内側のループ」だけを抜けるということです。
# 入れ子のループとbreak文
print("入れ子のループとbreak文:")
for i in range(3):
print(f"外側のループ: i = {i}")
for j in range(4):
print(f" 内側のループ: j = {j}")
if j == 1 and i == 1:
print(" 条件に一致したのでbreak")
break # 内側のループ(j)だけを抜ける
print("外側のループの1回分の終わり")
入れ子のループとbreak文:
外側のループ: i = 0
内側のループ: j = 0
内側のループ: j = 1
内側のループ: j = 2
内側のループ: j = 3
外側のループの1回分の終わり
外側のループ: i = 1
内側のループ: j = 0
内側のループ: j = 1
条件に一致したのでbreak
外側のループの1回分の終わり
外側のループ: i = 2
内側のループ: j = 0
内側のループ: j = 1
内側のループ: j = 2
内側のループ: j = 3
外側のループの1回分の終わり
この例では、i == 1
かつj == 1
の条件が満たされたときにbreakが実行されますが、内側のループ(j)だけが終了し、外側のループ(i)は続行されています。
入れ子のループとcontinue文#
continue文も入れ子のループで使うことができます。break文と同様に、continue文も自分が属する「最も内側のループ」だけに影響します。
print("入れ子のループとcontinue文:")
for i in range(3):
print(f"外側のループ: i = {i}")
for j in range(4):
if j == 1 and i == 1:
print(f" i = {i}, j = {j} の処理をスキップ")
continue # 内側のループ(j)の現在の繰り返しをスキップ
print(f" 内側のループ: i = {i}, j = {j}")
print("外側のループの1回分の終わり")
入れ子のループとcontinue文:
外側のループ: i = 0
内側のループ: i = 0, j = 0
内側のループ: i = 0, j = 1
内側のループ: i = 0, j = 2
内側のループ: i = 0, j = 3
外側のループの1回分の終わり
外側のループ: i = 1
内側のループ: i = 1, j = 0
i = 1, j = 1 の処理をスキップ
内側のループ: i = 1, j = 2
内側のループ: i = 1, j = 3
外側のループの1回分の終わり
外側のループ: i = 2
内側のループ: i = 2, j = 0
内側のループ: i = 2, j = 1
内側のループ: i = 2, j = 2
内側のループ: i = 2, j = 3
外側のループの1回分の終わり
この例では、i == 1
かつj == 1
の条件が満たされたときにcontinueが実行され、その繰り返しだけがスキップされ、内側のループの次の繰り返し(j = 2)に進みます。
実用例:かけ算表の作成#
入れ子のループの実用的な例として、九九のようなかけ算表を作成してみましょう。
# 掛け算表の作成
print("掛け算表(九九):")
# 1から9までの掛け算表
for i in range(1, 10):
for j in range(1, 10):
result = i * j
print(f"{result:2d}", end=" ") # 2桁で整列して表示
print() # 行の終わりで改行
掛け算表(九九):
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
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
この例では、入れ子のループを使って9×9のかけ算表を作成しています。外側のループが行(i)、内側のループが列(j)を処理し、各セルにi * j
の結果を表示しています。
実用例:パターンの出力#
入れ子のループを使うと、さまざまな模様やパターンを出力することができます。例えば、次のようなアスタリスクを使ったパターンを考えてみましょう。
# パターンの出力例
print("パターン出力の例:")
# 三角形のパターン
height = 5
print("\n三角形パターン:")
for i in range(1, height + 1):
for j in range(i):
print("*", end="")
print() # 行の終わりで改行
# 逆三角形のパターン
print("\n逆三角形パターン:")
for i in range(height, 0, -1):
for j in range(i):
print("*", end="")
print() # 行の終わりで改行
# ピラミッドパターン
print("\nピラミッドパターン:")
for i in range(1, height + 1):
# スペースを出力
for j in range(height - i):
print(" ", end="")
# アスタリスクを出力
for j in range(2 * i - 1):
print("*", end="")
print() # 行の終わりで改行
パターン出力の例:
三角形パターン:
*
**
***
****
*****
逆三角形パターン:
*****
****
***
**
*
ピラミッドパターン:
*
***
*****
*******
*********
これらの例では、外側のループが行数を、内側のループが各行の文字数を制御しています。「ピラミッドパターン」の例では、各行に適切な数のスペースとアスタリスクを出力するために2つの内側ループを使っています。
まとめ#
この記事では、Pythonの入れ子のループ(ループの中のループ)について学びました。
- 入れ子のループは、ループの中に別のループを配置することで、複数次元の繰り返し処理を実現する
- 外側のループが1回実行されるごとに、内側のループが最初から最後まで実行される
- 入れ子のループの実行回数は、各ループの繰り返し回数の掛け算で求められる
- 入れ子のループは、表形式のデータ処理や模様の出力など、様々な場面で役立つ
- break文とcontinue文は、自分が属する最も内側のループだけに影響する
入れ子のループは、複雑なデータ構造の処理や、複数の条件に基づいたアルゴリズムの実装に非常に役立ちます。効率的に使いこなせるようになれば、より柔軟なプログラムを書けるようになるでしょう。