Yamamoto's Laboratory
 
環境設定
 
プログラム作成
  書き方
 
繰り返し処理
 
 
 
tkinter
 
 
 
 
 
 

はじめに

Python では,for と while を使った繰り返し構文を使うことができます.前者は,リストのようなシーケンスに繰り返し処理を行う場合に使います.後者は,繰り返しの途中で処理の続行/中断を判断する場合に用います.Python には,とりあえず処理し最後に判断をする do はありません.

for による繰り返し

基本形

リストのようなシーケンスに順次アクセスし処理を行う場合に for による繰り返し構文が使われます.for の繰り返し文の基本構文は,以下の通りです(フローチャート).else 節はオプションで,無くても実行できます.

この構文では,シーケンスオブジェクトからひとつずつデータを取り出し変数に代入,そして繰り返し処理を行います.全ての処理が終わると,else 節の文を実行します.

for  変数  in   シーケンス:          # シーケンスはリストなど
    実行文 1
    実行文 2
    …
else:                                      # 無くても良い
    実行文 1
    実行文 2
    …

プログラム例

for を使った繰り返し処理のこのプログラム例をリスト 1 に示します.これは,a と b の二つのリストをシーケンスとして用いた二重ループ構造です.各リストの値がひとずつ変数 x と y に代入され,計算と表示の処理が行われます.そして,各ループの繰り返し処理が終わると else 節が実行されます.このことは,このプログラムの実行結果からも確認できます.

for による繰り返し(for.py) 実行結果
001   #!/usr/bin/python3
002   
003   a = [1, 2, 3]
004   b = [2, 4, 6]
005   
006   if __name__ == "__main__":
007       for x in a:
008           for y in b:
009               print(x," * ",y," = ", x*y)
010           else:
011               print("--------------------")
012       else:
013           print("finish")
1  *  2  =  2
1  *  4  =  4
1  *  6  =  6
--------------------
2  *  2  =  4
2  *  4  =  8
2  *  6  =  12
--------------------
3  *  2  =  6
3  *  4  =  12
3  *  6  =  18
--------------------
finish

シーケンス生成

range() 関数で整数リスト

よく使われる整数の値を変化させる繰り返し処理には,range 関数が便利です.この関数は,整数の数列からなるリストを返します.例えば,「for i in range(0, 100)」とすると,i の値を 0 から 99 まで変えてループ処理ができます.引数のパターンにより,range 関数はさまざまなリストを作成できます.代表的な range 関数の使い方を,以下に示します.

range 関数の例 動作(出力と説明)
range(0, 100) [0, 1, 2, 4, 5, 6, …, 99]
引数は (初期値, この値を超えない) です.この例では,0 から 99 までの整数のリストを返します.
range(6, 100, 2) [6, 8, 10, 12, 14, 18, …, 98]
引数は (初期値, この値を超えない, 増分) です.この例では,6 から 98 まで,増分が 2 の整数のリストを返します.
range(5, -99, -3) [5, 2, -1, -4, -10, -13, …, -97]
引数は (初期値, この値より小さくならない, 負の増分) です.この例では,5 から -97 まで,増分が -3 の整数のリストを返します.
range(60) [0, 1, 2, 4, 5, 6, …, 59]
引数は (この値を超えない) で,ゼロを初期値とします.この例では,0 から 99 までの整数のリストを返します.

多重ループ

python はインデントで制御ブロックの範囲を指定します.そのため,多重ループでは,インデントが深くなり,分かり難くなります.itertools.product() を使うと,インデント深くすること無く,多重ループが実現できます.例えば,以下の二つのプログラムは同じ結果になります.

通常の多重ループ(プログラムと実行結果)

for i in range(1,3):
    for j in range(2,4):
        for k in range(1, 10, 2):
            print('i:{0:d}\tj:{1:d}\tk:{2:d}'.format(i, j, k))

itertools.product()を使った多重ループ(プログラムと実行結果)

import itertools

for i, j, k in itertools.product(\
                range(1,3), range(2,4), range(1, 10, 2)):
    print('i:{0:d}\tj:{1:d}\tk:{2:d}'.format(i, j, k))

文字処理

文字列のリストが for で処理できることはいうまでもないですが,ひとつの文字列も処理できます.以下に具体例を示します.

リスト2 のプログラムには,二つのシーケンスがあります.003 行目の a と 004 行目の b です.a は 4 つ,b も 4 つの要素から成り立っています.008 行目では zip 関数を使い,それぞれのシーケンスから要素を取り出して,タプルを作成します.このタプルのシーケンスの要素を (x, y) に代入し,繰り返し処理を行います.二つ以上のシーケンスを同時に取り扱う場合には,zip 関数が便利です.

このプログラムの実行結果は,以下の通りです.

文字列の処理(for_string.py) 実行結果
001   #!/usr/bin/python3
002   
003   a = "HTML"
004   b = ["Hyper", "Text", "Markup", "Language"]
005   
006   if __name__ == "__main__":
007       print("--------------------")
008       for (x, y) in zip(a, b):
009           print(x, "\t", y)
010       else:
011           print("--------------------")
--------------------
H        Hyper
T        Text
M        Markup
L         Language
--------------------

この例では,003 行目のオブジェクト a は文字列ですが,ひとつずつの文字のシーケンスとして取り扱っている点に注意が必要です.

ファイル処理

テキストファイルからデータを読み込む場合,しばしば for の繰り返し構文が使われます.

while による繰り返し

基本形

while の繰り返し文の基本構文は,以下の通りです(フローチャート).else 節はオプションで,無くても実行できます.

while  条件:               # 条件はTrue or False
    実行文 1
    実行文 2
    …
else:                         # 無くても良い
    実行文 1
    実行文 2
    …

プログラム例

以下に,while を使った二重ループのプログラムと実行結果を示します.

while による繰り返し(while.py) 実行結果
001   #!/usr/bin/python3
002   
003   if __name__ == "__main__":
004       x = 1
005       while  x <= 3:
006           y = 2
007           while y <= 6:
008               print(x," * ",y," = ", x*y)
009               y += 2
010           else:
011               x += 1
012               print("--------------------")
013       else:
014           print("finish")
1  *  2  =  2
1  *  4  =  4
1  *  6  =  6
--------------------
2  *  2  =  4
2  *  4  =  8
2  *  6  =  12
--------------------
3  *  2  =  6
3  *  4  =  12
3  *  6  =  18
--------------------
finish

繰り返し途中でのループの中断

次のループへ (continue)

for や while のループ中で,continue 文に出会うと以降のループ内の実行文はスキップし,先頭に戻ります(フローチャート).

continue によるループのスキップ(continue.py) 実行結果
001   #!/usr/bin/python3
002   
003   if __name__ == "__main__":
004       x = 0
005       while  x<10:
006           x += 1
007           print(x,": ", end="")
008           if(5<x):
009               print(end="\n")
010               continue
011           print(x**2,"\t", x**3)
012       else:
013           print("finish")
1 : 1    1
2 : 4    8
3 : 9    27
4 : 16   64
5 : 25   125
6 : 
7 : 
8 : 
9 : 
10 : 
finish

ループの終了 (break)

for や while のループ中で,break 文に出会うループから脱出します(フローチャート).この場合,else 節は実行されません.また,多重ループの場合には最も内側のループしか脱出できません.Python には多重ループを使った構文が無いので,その場合にはなにがしかの工夫が必要です.

break によるループの終了(break.py) 実行結果
001   #!/usr/bin/python3
002   
003   if __name__ == "__main__":
004       x = 0
005       while  x<10:
006           x += 1
007           print(x,": ", end="")
008           if(5<x):
009               print(end="\n")
010               break
011           print(x**2,"\t", x**3)
012       else:
013           print("finish")
1 : 1    1
2 : 4    8
3 : 9    27
4 : 16   64
5 : 25   125
6 :

イタレーター関数(itertools)

itertools は繰り返し処理における効率的なイタレーターを生成します.

無限のイタレーター

以下の表に示す関数は終わりのないイタレーターを生成します.表中の関数の引数のうち,角括弧内は,省略可能です.終わりの無いイタレーターなので,そのままでは無限ループに陥ります.ループの終了条件,例えば if と break が必要です.

関数 動作
count(start [, step]). start から始まる数で,間隔: step のイタレーター (プログラム例) count(5): 5, 6, 7, …
cycle(sequence). シーケンスを繰り返します (プログラム例). cycle([1,2,3]): 1, 2, 3, 1, 2, 3, 1, …
repeat(elem [,n]) elem を n 回繰り返します.n を指定しない場合は無限の繰り返し (プログラム例). repeat(8): 8, 8, 8, 8, 8, …

最短の入力シーケンスで停止

下表のイタレーターは,終わりがあります.

関数 動作
accumulate(p [, func]) 累積.関数を指定しない場合は,p0, p0+p1, p0+p1+p2, ….関数を指定すると,n番目のイタレーター an=f(an-1, pn)となります.ただし,a0=p0(プログラム例) accumulate([1, 2, 3, 4, 5]): 1, 3, 6, 10, 15
chain(p, q [,]) シーケンスを順に出力します(プログラム例). chain([1,2,3], 'abc'): 1, 2, 3, a, b, c
chain.from_iterable(p, q [,]) イタレート可能なシーケンスを順に出力します(プログラム例). chain.from_iterable('ABC', 'XYZ'): A, B, C, X, Y, Z
compress(p, s) s[i]のブール値に依存して,シーケンス p[i] を出力します(プログラム例). compress('ABCDE',[1,0,1,0,1]): A, C, E
dropwhile(pred, p) pred が False になった時に,シーケンス p[i] を出力を開始します(プログラム例). dropwhile(lambda x: x<5, [1,4,6,4,1]): 6, 4, 1
filterfalse(pred, p) pred が False の時に,シーケンス p[i] を出力します(プログラム例). filterfalse(lambda x: x<5, [8,4,6,4,1,9]): 8, 6, 9
groupby(p, key) シーケンス p を key グループ化したイタレーターを出力します.key の値が変わった時に,次のグループになります(プログラム例). groupby(['aa', 'yb', 'yc', 'as'], key=lambda x: x[0]): a: 'aa',y: ('yb', 'yc'),a: 'as'
islice(p, [start, ] stop [, step]) シーケンス p を start から stop まで,step 間隔で出力します(プログラム例). islice('abcdefghijkemnop', 2, 12, 2): c, e, g, i, k
starmap(func, p]) シーケンス: p を 関数: func に適用して出力します(プログラム例). starmap(max, [(-2,3), (6,4), (-8,9)]): 3, 6, 9
takewhile(pred, p]) pred が偽(False)になるまで,シーケンス:pを出力します(プログラム例). takewhile(lambda x: x<3, [0, 1, 2, 3, 4, 5]): 0, 1, 2
tee(p, n]) 独立した n 個のイタレーターを生成します(プログラム例). a,b=itertool.tee(range(30),3)
zip_longest(p, q [, …]) 最も長いシーケンスに合わせて,複数のシーケンスをタプルで出力します.先に端に達したシーケンスの値は,None になります(プログラム例). zip_longest('ABCDE', 'abc'): ('A', 'a'), ('B', 'b'), ('C', 'c'), ('D', None), ('E', None)

シーケンスの組み合わせのイタレーター

シーケンスを組み合わせて,イタレーターを生成します.

関数 動作
product(p, q [, …]) シーケンスの組み合わを,イタレーターとして出力します(プログラム例). product('AB', 'abc'): ('A', 'a'), ('A', 'b'), ('A', 'c'), ('B', 'a'), ('B', 'b'), ('B', 'c')
permutations(p [,r]) シーケンス p から r 個選んだ順列をイタレーターとして出力します.r を指定しない場合はシーケンスの長さの順列になります(プログラム例). permutations('ABC'): ('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')
combinations(p r) シーケンス p から r 個選んだ組み合わせを,イタレーターとして出力します(プログラム例). combinations('ABC'): ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')
combinations_with_replacement(p r) シーケンス p から r 個選んだ組み合わせを,ソートされた順でイタレーターとして出力します.(プログラム例). combinations_with_replacement('ABC'): ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')

ページ作成情報

参考資料

  1. open 関数に関しては,Python 3.4.2 ドキュメント組み込み関数 open()を参考にしました.
  2. itertools について,「itertools ― 効率的なループ実行のためのイテレータ生成関数」が最も参考になります.原文の英語のサイトは「itertools ― Functions creating iterators for efficient looping — Python 3.6.5 documentation」です.

更新履歴

2014年12月22日 ページの新規作成


no counter