Lesson05 ループ(1)for 文

イメージ画像

単純作業を繰り返すために便利な構文ループを学ぼう

  • for ループの使い方

コンピュータは数字の処理は大変得意です。数字の処理について、基本的な四則演算について学びました。たとえば、1 から 1000 までの整数を順にたすといくといった作業を人間がすると、単純作業ですが、式を打ち込むだけで時間がかかります。
この例では、人間であれば、1 ~ n までの整数の総和が n*(n+1)÷2 で計算できることを知っている人はすぐに 1000×1001÷2 で計算するでしょう。

コンピュータは、公式を教えなければ、愚直に 1 + 2 + 3 + … +1000 を計算します。

逆に言うと、公式がないような複雑で膨大なデータを処理するときは計算するしかありませんが、コンピュータはこのような同じ動作を愚直におこなうことが得意です。同じような繰り返し作業をするための構文がループです。
今回は、単純作業を繰り返すために便利な構文であるループを学びます。ループの処理はいくつかありますが、今回は for 文について学びます。

今使うソースコードはここからまとめてダウロードできます。 ダウンロードfile_download

前回の復習

前回はコードレビューによって自分以外の人が書いてコードを見て、添削される様子を見ました。
また、ランダムに数字を発生させる方法と、その関数を使うためのモジュールの中の関数を呼び出す方法について学びました。

前回出た重要キーワード

  • import
  • randint(A,B)
  • モジュール
  • pass
  • フローチャート
  • print や input のような関数はそのまま使えますが、モジュールと呼ばれる便利な機能が集まったものに入っている関数は import を使ってその関数を使うことを宣言しなければいけませんでした。
  • randint() 関数は random モジュールに含まれる関数で、randint(A,B) のようにして呼び出すと、A 以上 B 以下の整数がこの関数が使われるたびにつくられるのでした。
  • pass は、何もしない関数でした。
  • フローチャートは処理を図に表したもので、3 つのプログラムをフローチャートにしました。フローチャートについては後で詳しく学びます。今はフローチャートというものがある、程度でかまいません。
  • 真偽は、if文で条件が一致するときが「真」、そうでないときが「偽」だと学びました。数字は0以外は真で0は偽になります。
  • and/or は条件を AかつBにするか A or Bにするかで使います。
    if A and B は 条件Aと条件Bが両方が成立するとif文の中の処理が実行されます。また、if A or B は条件Aと条件Bの少なくとも一方が方成立すればif文の中の処理が実行されます。
  • if文の中にif文を入れることをネスト(入れ子)と呼びます。

1for ループ

この章のキーワード

  • ループ
  • for文
  • range関数
  • break
  • continue
  • ループ変数のインクリメント

ソースコードは上から下に処理されると第1回の授業でならいました。
が、しかし実はこれは本当は正しくありません。上から下へ行き、下から上へ戻るという処理もあるのです。それをループ処理と言います。

1.1 for ループの基本的な使い方

for ループ変数 in range(最初の整数,最後の整数+1):
    繰り返す処理(しばしばループ変数を使う処理)

繰り返す文がインデントされているところです。for 文の中の繰り返す処理は必ずインデントされなければ行けません。インデントを戻すとそこはループの外になります。

for文の基礎

for文の例

for文の例

ループの例1:(lesson005_01.py) 1から10までの整数を print 関数で列記する

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

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
1
2
3
4
5
6
7
8
9
10

range(1,10) でなく range(1,11) であることに注意してください。

つまり、次の2つのコードは同じです。

 1
 2
for k in range(1,11) : 
    print(k)
 1
 2
for loop_hensu in range(1,11) : 
    print(loop_hensu)

ループの例2:(lesson005_02.py) 1 から 10 までの整数を 2 倍したものを列記する

 1
 2
 3
for i in range(1,11) : 
    print( 2*i )
  # 反復処理

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
2
4
6
8
10
12
14
16
18
20

ループの中で自動的に変化するループ変数( i )と、ループの外で定義されループ内で操作される変数(S)を使うと、複数の整数の和を求めることができます。

ループの例3 :(lesson005_03.py) 1 からある整数までの総和を求める

 1
 2
 3
 4
 5
 6
 7
 8
S = 0 #総和を保持する変数
for i in range(1, 1000):
    S = S + i
    # 高校で習う「漸化式」で書くと S_{i+1} = S_{i} + i

print("999までの整数の和は")
print(str(S))
print("です")

なお、このプログラムは、S は i という添え字をもつ S(i) という数列だとすると、
S(i+1) = S(i) + i , S(0) = 0 として、i を 1 から 999 まで動かすのと同じ挙動をします。
S(i) は、 S0 から i までの整数の和を表す数列です。最後の結果である print 関数で表示しているのは S(999) となるわけです。

なお、ループの中ではiは1から始まるのに、なぜ1行目でS=0を定義しなければいけないのでしょうか。ためしに 1 行目をコメントアウトして実行してみましょう。

 1
 2
 3
 4
Traceback (most recent call last):
  File ".\lesson005_03.py", line 3, in module
    s = s + i
NameError: name 's' is not defined

エラーになります。最初の値がきまらないので、その後が帰納的に定まらないのです。

高校で学習する漸化式は、数列の帰納的定義ですが、漸化式だけでは数列は決まらず、必ず初項を決めないといけませんね。先頭の S =0 はまさに、この初項を定義しているのです。

1.2 for ループをスキップする contiue と中止する break

ループの中で途中であるときはループをスキップしたり、ループ処理を中止したいことがあります。それぞれ continue, break という制御文が用意されています。

continue は、そこでループの処理を終えて、はじめに戻ります。

ループをスキップしてもう一度ループに入るときは continue

continue でループの先頭に戻ってループ変数が 1 増える
for ループ変数 in range(最初の整数,最後の整数+1):
    continue

例:奇数の時だけスキップする (lesson005_04.py)

 1
 2
 3
 4
for k in range(1,10):
    if k % 2 :
        continue
    print(k)

break はそこでループの処理そのものを中止してループを抜けます。
ループを抜けるときは break

break でループを抜ける
for ループ変数 in range(最初の整数,最後の整数+1):
    break

6 以上になればループを抜ける (lesson005_05.py)

 1
 2
 3
 4
for k in range(1,10):
    if k > 5 :
        break
    print(k)

実行結果

 1
 2
 3
 4
 5
1
2
3
4
5

1.3 for ループの別の書き方

for ループを range で使う時は、range 関数の使い方が何通りかあります。

range 関数の引数を1つだけにする

for ループ変数 in range(繰り返す数):

range の引数を 1 つだけにすると、0 からその数字の手前までの整数を順にループ変数として処理します。

 1
 2
for k in range(4):
    print(k)

これは以下と同じコードになります。

 1
 2
for k in range(0,4):
    print(k)

実行結果

 1
 2
 3
 4
0
1
2
3

range 関数の引数を3つにする

for ループ変数 in range(初めの数 , 最後の数より1つ大きい数 ,ステップ):

これまでは、3 つ目の引数は省略していましたが、1 以外の数字を入れることができます。

 1
 2
for k in range(1,20,3):
    print(k)

この例では、ループ変数である k は、1 から始まり、3ずつ大きくなります。

実行結果

 1
 2
 3
 4
 5
 6
 7
1
4
7
10
13
16
19

1.4 for ループのネスト

if のところで入れ子にすることをネストと言うと習いました。if と同じように for 文もネストすることができます。

for 1つ目のループ変数 in range(初めの数 , 最後の数の1つ大きい数 ,ステップ):
    for 2つ目のループ変数 in range(初めの数 , 最後の数の1つ大きい数 ,ステップ):
         何か繰り返す処理

九九の表を作ってみましょう。(lesson005_06.py)

 1
 2
 3
 4
 5
 6
 7
##九九を表示するプログラム
for k in range(1,10):
    print(str(k) + "の段の九九を表示します。")
    for j in range(1,10):
        kuku = k*j
        print(str(k) + '×' + str(j) + "=" + str(kuku))
    print("") #1行をあけるため

実行結果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1の段の九九を表示します。
1×1=1
1×2=2
1×3=3
1×4=4
1×5=5
1×6=6
1×7=7
1×8=8
1×9=9

2の段の九九を表示します。
2×1=2
2×2=4
2×3=6

…(中略)…

9の段の九九を表示します。
9×1=9
9×2=18
9×3=27
9×4=36
9×5=45
9×6=54
9×7=63
9×8=72
9×9=81

for 文の中の繰り返すところはネストするので for の中の for ではインデントは2つ分になります。

演習の時間

演習の解答はここからダウンロードできます。ダウンロードfile_download

演習1

for ループを使って、1から数えて N 番目の奇数までを列記するプログラムを書いてください。ただし、N は、キーボードから入力し、自由に決められるものとします。enshu005_01.py の名前で保存してください。

期待される動作(青い文字はキーボードから入力)

何番目までの奇数を表示しますか
4
1番目の奇数: 1
2番目の奇数: 3
3番目の奇数: 5
4番目の奇数: 7

演習2

1は1番目の奇数、3 は2番目の奇数、5 は3番目の奇数という風に番号をつけると、
11 は5 番目の奇数になります。
5 番目の奇数である 11 までの奇数の総和を求めてみましょう。
すなわち、 1 + 3 + 5 + 7 + 9 + 11 = 36 ですね。

input 関数を使って、キーボードから奇数の番号を入力させ、その奇数までの総和を求めるプログラムを書いてください。enshu005_02.py の名前で保存してください。

ヒント

1 番目の奇数は 1
2 番目の奇数は 3
3 番目の奇数は 5
4 番目の奇数は 7
・・・
k 番目の奇数は ??
・・・

期待される動作(青い文字はキーボードから入力)

何番目までの奇数の和を求めますか
100
100番目の奇数は2001です。
1から2001までの奇数だけを足し合わせると10000になります。

このプログラムのソースコードは下記のようになります。はてなを埋めて完成させてみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
print(“何番目までの奇数の和を求めますか。”)
kisuu = input()
kisuu = int(kisuu)
s = 0 #sは総和を保持する変数
for k in range(1,kisuu) : 
    s = s + ????    
print( “番目の奇数は” ) 
print(“1から” + ???? +  “までの奇数だけを足し合わせると”+ ???? +”になります”)

演習3

Lesson03 の演習 3 で作成した FizzBuzz のプログラムをベースにして、1~100 までのFizzBuzz ゲームでなんと答えるか正解を表示するプログラムを書きましょう。
enshu005_03.py の名前で保存してください。

期待される動作

1番目の人:1
2番目の人:2
3番目の人:Fizz
4番目の人:4
5番目の人:Buzz
6番目の人:6
7番目の人:7
8番目の人:8
9番目の人:Fizz
10番目の人:Buzz
・・・・
100番目の人:Buzz

時間があまったあなたに

1以上100以下の整数を10000個作ろう

for 文とランダム関数 randint を使って、1 以上 100 以下の整数を 10000 個作ってみましょう。

この 10000 個の数字のうち、10 以下の数字は何個くらいあるでしょうか?どの数字も等しい確率であるとすると、全体の 10 % なので、1000 個程度だと予想されます。
実際にそのようになっているか確認するプログラムを書いてください。

期待される動作

今から1以上100以下の整数をランダムに10000個作ります。
23
99
32
55
5
…(中略)…
このうち10以下の数字は990個ありました。

大人のあなたへ

range は関数。別の関数に置き換えた書き方もある?

今回、for 文を以下の構文で学びました。

for ループ変数 in range(初めの数 , 最後の数の1つ大きい数 ,ステップ):
    何か繰り返す処理

range は関数です。では、この range のところを別の関数に置き換えた書き方もあるのでは?と思った人がいるかもしれません。その通りです。

実は、for 文はもう少し一般的な書き方ができます。

for ループ変数 in イテラブルなオブジェクト :
    何か繰り返す処理

さて、イテラブルという言葉が出てきました。イテラブルとは繰り返しできる「もの」です。Pythonでは、オブジェクトといいます。つまり in のあとはイテラブルなオブジェクトであればよいわけです。

range 関数は、後で学ぶリストというデータのタイプを返します。リストという種類のオブジェクトもまたイテラブルなオブジェクトです。このほかにもリストでないイテラブルなオブジェクトを置くこともできます。