Python基礎講座 #15 for文 (for loop)

読了 7分

今日の講座ではfor文について勉強していきましょう。

Pythonのfor文は、データのコレクションを順次処理するために使われる構文です。 while反復文と似た機能を持っていますが、ほとんどの場合while反復文より便利に使われる反復文です。 すべてのシーケンス型のオブジェクトはfor文で使えます。 for文で使用可能なオブジェクトかどうかは、iter関数を使って確認できます。 for文で使えるシーケンス型のオブジェクトには、文字列、リスト、辞書、タプル、セット、rangeオブジェクトがあります。

For文で使用可能なシーケンス型オブジェクト

  • String
  • List
  • Dictionary
  • Tuple
  • Set
  • Range

for文で使えないオブジェクトには、シーケンス型ではない、integer、float、boolean、None、functionオブジェクトなどがあります。

For文で使えないオブジェクト

  • Integer
  • Float
  • Boolean
  • None
  • Function

前にiter関数を使ってfor文で使えるオブジェクトかどうかを区別できると説明しました。あるオブジェクトをiter関数の引数として渡して実行したときにiteratorオブジェクトが返されればfor文で使えるオブジェクトであり、型エラーが発生すればfor文で使えないオブジェクトです。

for文で使えるオブジェクトをiter関数を使って確認してみましょう。

# for 文で使えるオブジェクト
my_string = 'abc'
my_list = [1, 2, 3]
my_dict = {'a': 1, 'b': 2}
my_set = {'a', 'b', 'c'}
my_range = range(10)

print('String: {}'.format(iter(my_string)))
print('List: {}'.format(iter(my_list)))
print('Dictionary: {}'.format(iter(my_dict)))
print('Set: {}'.format(iter(my_set)))
print('Range: {}'.format(iter(my_range)))
String: <str_iterator object at 0x000001F326934BB0>
List: <list_iterator object at 0x000001F3247614F0>
Dictionary: <dict_keyiterator object at 0x000001F3274E0860>
Set: <set_iterator object at 0x000001F3274EFC00>
Range: <range_iterator object at 0x000001F326908D10>

for文で使えるオブジェクトをiter関数の引数として渡したところ、すべてiteratorオブジェクトを返すのを見ました。

次はfor文で使えないオブジェクトを確認してみましょう。

for文で使えないオブジェクトも確認してみましょう。

# for 文で使えないオブジェクト
my_integer = 1
my_float = 1.234
my_bool = True
my_none = None
def my_func():
pass

print('Integer: {}'.format(iter(my_integer)))

TypeError: 'int' object is not iterable

for文で使えないオブジェクトをiter関数の引数として渡したところ、すべてiterableオブジェクトではないという型エラーを発生させました。Float、boolean、None、functionオブジェクトも直接確認してみてください。

iterableオブジェクトである文字列をfor文で実行してみましょう。

my_string = 'abc'

for letter in my_string:
print(letter)

a
b
c

for文が実行されながら、letterという変数に文字が1つずつ保存されていくのが分かります。

for文は内部的にどのように動作するのでしょうか。for文がどう動作するかを理解するためには、まずiter関数とnext関数を理解する必要があります。

文字列をiter関数に渡してstr_iteratorオブジェクトを作り、str_iteratorが持っている__next__関数を使って文字を1つずつ出力してみましょう。

iter_obj = iter('abc')

print(iter_obj)
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())

<str_iterator object at 0x000001F324761250>
a
b
c
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
in
5 print(iter_obj.__next__())
6 print(iter_obj.__next__())
----> 7 print(iter_obj.__next__())

a、b、cが順次出力されたあと、もう出力する文字がないためStopIterationエラーが発生するのが分かります。iter関数はシーケンスオブジェクトを引数として受け取り、iteratorオブジェクトを返します。こうして作られたiteratorオブジェクトは__next__メソッドを持っており、このnextメソッドを実行すると、文字を1つずつ順番に返します。そして、もう返す文字が残っていなければStopIterationエラーを発生させます。

for文の中ではcontinue、breakの2つのキーワードが使えます。continueは目的のシーケンスをスキップせよ、という命令で、breakはfor文を終了せよ、という命令です。1つずつ使ってみましょう。

my_list = ['one', 'two', 'three', 'skip', 'four', 'five']

for num in my_list:
if num == 'skip':
continue  # 返された値が 'skip' と等しければスキップします。

    print(num)

    if num == 'four':
        break  # 返された値が 'four' であれば for 文を終了します。

one
two
three
four
for文を使っているとアンパッキング (unpacking) という機能を使わなければならないことがありますたとえば下のリストのようにリストで作られたリストをfor文で実行するとi変数にリストオブジェクトが保存されます

list_1 = [[1, 2], [3, 4], [5, 6]]

for i in list_1:
print(i)

[1, 2]
[3, 4]
[5, 6]

しかしfor文の中に変数を2つ定義すると、リストアイテムが各変数に1つずつ保存されることになります。これをアンパッキングと言います。

list_1 = [[1, 2], [3, 4], [5, 6]]

for i, j in list_1:
print(i, j)

1 2
3 4
5 6

もちろん下のコードのようにネストしたfor文を使って各アイテムにアクセスすることもできますが、アイテムが多くなければアンパッキングを使うほうが便利です。

アンパッキングは次のようにアイテムが2つ以上であっても使えます。

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

for i, j, k in list_2:
print(i, j, k)

1 2 3
4 5 6
7 8 9

ただし、以下のようにアンパッキングするアイテムの数と変数の数が一致しないとエラーが発生します。

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

for i, j in list_2:
print(i, j)
 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-19b25bdbc030> in <module>
2 list_2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3
----> 4 for i, j in list_2:
5     print(i, j)

ValueError: too many values to unpack (expected 2)

今度は辞書をfor文で使う方法を見ていきましょう。シンプルな辞書を定義したあと、for文の中で実行してみましょう。どんな値が出力されるでしょうか。

my_dict = {
'a': 1,
'b': 2,
'c': 3
}

for i in my_dict:
print(i)

a
b
c

辞書をfor文で実行すると、各アイテムのvalueではなくkeyが返されます。そのため辞書をfor文で使う場合は、次のように返されたkeyを使ってvalueにアクセスする必要があります。

my_dict = {
'a': 1,
'b': 2,
'c': 3
}

for key in my_dict:
print('{}: {}'.format(key, my_dict[key]))

a: 1
b: 2
c: 3

別の方法としては、itemsメソッドを使うこともできます。

my_dict = {
'a': 1,
'b': 2,
'c': 3
}

for i in my_dict.items():
print(i)

('a', 1)
('b', 2)
('c', 3)

itemsメソッドを使うと、タプルオブジェクトとしてkeyとvalueが返されます。この場合はアンパッキングを使ってください。

my_dict = {
'a': 1,
'b': 2,
'c': 3
}

for k, v in my_dict.items():
print('{}: {}'.format(k, v))

a: 1
b: 2
c: 3

セットもfor文で使えます。ただしセットは順序がないオブジェクトなので、for文でも保存された順序とは関係なく返されるという点をぜひ覚えておいてください。実行してみましょう。

my_set = {'a', 'b', 'c'}

for i in my_set:
print(i)

c
b
a

最後にrangeオブジェクトを使ってみましょう。

range関数は、特定の数だけfor文を実行したいときによく使われます。たとえば、1から10までの数を出力したい場合は、次のようなコードを実行してください。

for i in range(1, 11):
print(i)

1
2
3
4
5
6
7
8
9
10

コーディング試験の問題として、反復文を使って九九を作るという問題がよく出されます。For文とrange関数を使って九九を出力してみましょう。

for i in range(1, 10):
for j in range(2, 10):
result = '{} x {} = {}'.format(j, i, j * i)
print('{:10s}'.format(result), end='\\t')
print()

2 x 1 = 2 	3 x 1 = 3 	4 x 1 = 4 	5 x 1 = 5 	6 x 1 = 6 	7 x 1 = 7 	8 x 1 = 8 	9 x 1 = 9
2 x 2 = 4 	3 x 2 = 6 	4 x 2 = 8 	5 x 2 = 10	6 x 2 = 12	7 x 2 = 14	8 x 2 = 16	9 x 2 = 18
2 x 3 = 6 	3 x 3 = 9 	4 x 3 = 12	5 x 3 = 15	6 x 3 = 18	7 x 3 = 21	8 x 3 = 24	9 x 3 = 27
2 x 4 = 8 	3 x 4 = 12	4 x 4 = 16	5 x 4 = 20	6 x 4 = 24	7 x 4 = 28	8 x 4 = 32	9 x 4 = 36
2 x 5 = 10	3 x 5 = 15	4 x 5 = 20	5 x 5 = 25	6 x 5 = 30	7 x 5 = 35	8 x 5 = 40	9 x 5 = 45
2 x 6 = 12	3 x 6 = 18	4 x 6 = 24	5 x 6 = 30	6 x 6 = 36	7 x 6 = 42	8 x 6 = 48	9 x 6 = 54
2 x 7 = 14	3 x 7 = 21	4 x 7 = 28	5 x 7 = 35	6 x 7 = 42	7 x 7 = 49	8 x 7 = 56	9 x 7 = 63
2 x 8 = 16	3 x 8 = 24	4 x 8 = 32	5 x 8 = 40	6 x 8 = 48	7 x 8 = 56	8 x 8 = 64	9 x 8 = 72
2 x 9 = 18	3 x 9 = 27	4 x 9 = 36	5 x 9 = 45	6 x 9 = 54	7 x 9 = 63	8 x 9 = 72	9 x 9 = 81

九九がとても簡単に作れることを見ていただきました。

今日の講座はここで終えて、次の講座では関数について勉強していきましょう。

X