P - 2.01.いろいろなfor文 Editorial /

Time Limit: 0 msec / Memory Limit: 0 KiB

前のページ | 次のページ

キーポイント

  • for 文を使うとループ処理を行うことができる
  • range 関数を使うと指定した範囲の処理を行うことができる
  • リストの各要素に対して処理を行うこともできる
  • enumerate, zip, reversed なども便利

R - 2.01.いろいろな for 文

for 文は第 1 章でも扱いましたが、より発展的な書き方も含めいろいろな書き方を紹介します。

range を使う書き方

1.09 節で扱った内容の復習です。 range 関数を使うと指定した範囲のループ処理を行うことができます。

range(stop)

stop 未満の整数をループします。

# 0 以上 5 未満をループ
for i in range(5):
    print(i)
実行結果
0
1
2
3
4

range(start, stop)

range 関数に引数を 2 つ指定すると、その範囲をループします。

# 2 以上 5 未満をループ
for i in range(2, 5):
    print(i)
実行結果
2
3
4

range(start, stop, step)

range の第 3 引数は、ループのステップを指定できます。

# 4 以上 10 未満の範囲を 2 ずつ増やしながらループ
for i in range(4, 10, 2):
    print(i)
実行結果
4
6
8

第 3 引数に負の整数を指定した場合、数値を減らしながらループします。

# 5 から 0 まで降順にループ
for i in range(5, -1, -1):
    print(i)
実行結果
5
4
3
2
1
0

リストなどに対する for 文

リストに対する for 文

単純なリストに対する for 文は 1.10 でも扱いました。

L = [10, 20, 40, 80, 160]

# L の要素を順に出力
for x in L:
    print(x)
実行結果
10
20
40
80
160

文字列に対する for 文

文字列に対して for 文を使うと、 1 文字ごとに処理することができます。より一般的な型の変数に対する for 文については「発展的な内容」も参照してください。

S = "AtCoder"

# s の要素を順に出力
for x in S:
    print(x)
実行結果
A
t
C
o
d
e
r

リストのリスト

リストのリスト

リストを要素とするリストの場合などには、カンマ区切りで受け取ると複数の変数に一気に格納することができます。

L = [[5, 10], [6, 20], [7, 50]]
for a, b in L:
    print("a は", a, "です。 b は", b, "です。")
実行結果
a は 5 です。 b は 10 です。
a は 6 です。 b は 20 です。
a は 7 です。 b は 50 です。

3 要素以上の場合

内側のリストが 3 要素以上になっても同様に書けますが、受け取る側の引数の個数が異なるとエラーになるので注意してください。

L = [[1, 2, 3], [4, 5, 6]]
for a, b, c in L:
    print("a は", a, "です。 b は", b, "です。 c は", c, "です。")

実行結果
a は 1 です。 b は 2 です。 c は 3 です。
a は 4 です。 b は 5 です。 c は 6 です。

次の例では長さ 4 の配列を 3 つの変数( a, b, c )で受け取ろうとしているため、 ValueError: too many values to unpack (expected 3) というエラーになります。

L = [[1, 2, 3, 4], [5, 6, 7, 8]]
for a, b, c in L:
    print("a は", a, "です。 b は", b, "です。 c は", c, "です。")


enumerate

enumerate 関数を使うと、リストのインデックスと要素をまとめて取得できます。

L = [10, 20, 40, 80, 160]

# L のインデックスと要素を取得
for i, x in enumerate(L):
    print(i, "番目の要素は", x)
実行結果
0 番目の要素は 10
1 番目の要素は 20
2 番目の要素は 40
3 番目の要素は 80
4 番目の要素は 160

インデックスは 0 から始まる点に注意してください。開始インデックスを明示的に指定したい場合は、第2引数に指定します。

L = [10, 20, 40, 80, 160]

# インデックスを 10 から開始
for i, x in enumerate(L, 10):
    print(i, "番目の要素は", x)
実行結果
10 番目の要素は 10
11 番目の要素は 20
12 番目の要素は 40
13 番目の要素は 80
14 番目の要素は 160

リストを逆順に処理

reversed 関数を使うと、リストを逆順に処理することができます。

L = [10, 20, 40, 80, 160]

# L の逆順
for a in reversed(L):
    print(a)
実行結果
160
80
40
20
10

リストの場合は reversed(L) の代わりに 1.10 節で扱ったスライスを使って L[::-1] と書いても逆順に処理することができます。

zip

複数のリストを同時に前からループ処理したい場合、 zip 関数が便利です。

A = [3, 4, 5, 6, 7]
B = [10, 20, 40, 80, 160]

# A と B から 1 つずつ要素を取得し a および b に格納する
for a, b in zip(A, B):
    print(a, b)
実行結果
3 10
4 20
5 40
6 80
7 160

ふたつのリストの長さが異なる場合は短い方が終わるまで処理されます。

A = [3, 4, 5, 6, 7, 8, 9, 10]
B = [10, 20, 40, 80, 160]

# A と B から 1 つずつ要素を取得し a および b に格納する
for a, b in zip(A, B):
    print(a, b)
実行結果
3 10
4 20
5 40
6 80
7 160

continue, break, else

こちらも 1.09 節で扱いましたが、復習のため再度紹介します。

continue

continue はその後の処理を飛ばします。

for i in range(5):
    # i == 2 の場合はその後の処理を飛ばす
    if i == 2:
        continue
    print(i)
実行結果
0
1
3
4

break

ループを抜ける場合は break を使います。

for i in range(5):
    # i == 2 の場合はループを抜ける
    if i == 2:
        break
    print(i)
実行結果
0
1

break-else

break を含むループ処理の後に else 節を書くと、 break で抜けなかった場合にのみ else 節が処理されます。
次の例では break により抜けるので else 節は処理されません。

for i in range(5):
    if i == 2:
        break
    print(i)
else:
    print("else 節が処理されたよ")
実行結果
0
1

次の例では break により抜けないので、 else 節が処理されます。

for i in range(5):
    if i == 7:
        break
    print(i)
else:
    print("else 節が処理されたよ")
実行結果
0
1
2
3
4
else 節が処理されたよ

発展的な内容

イテラブルオブジェクト

本節では主にリストや文字列の要素を順に処理するループを紹介しましたが、より一般的には イテラブル(iterable) なオブジェクトに対して同様の処理を行うことができます。イテラブルなオブジェクトとは、要素を一つずつ順番に取り出すことができるオブジェクトのことです。 listtuplestrsetdict などがイテラブルオブジェクトに該当し、これらはfor文などで逐次的に処理できます。また本節では range を使う書き方はおまじないのように説明しましたが、 range もイテラブルオブジェクトのひとつです。

問題

リンク先の問題を解いてください。