ホーム»プログラミング» 【プログラミング】[独学][Python-第5回]繰り返し(ループ)処理のコードを書く方法
a

【プログラミング】[独学][Python-第5回]繰り返し(ループ)処理のコードを書く方法

プログラミング

前回までは、文字出力や変数コレクションを用いたデータ、IF文を用いた条件分岐の扱い方について紹介しました。

今回で第5回目となりますが、第4回の条件分岐と合わせて非常に多くのシーンで使われることになるものですので、しっかりと内容を抑えておきたい部分となっています。

今回紹介するものは「繰り返し処理」と呼ばれるもので、主にwhileやforを用いたコードとなりますが、これはPythonに関わらず、プログラミングにおいて凄く重要な処理であり、特定の回数や条件に合致するまで繰り返し実行するプログラムを作る際に書きます。

前回の条件分岐との組み合わせが身につき、色々なシーンでの使い方に応用出来れば自動化できる作業も多くなってきます。
これにより、プログラミング初心者としてもかなり上達したような実感を得ることが出来るため上手くいった時の達成感も強くなってきます。

<strong>Deviko</strong>
Deviko

「繰り返し処理」・・・。なんだか難しい表現でピンとこない。

<strong>komori</strong>
komori

〇〇処理と言うと難しい表現に聞こえますが、要するに命令を繰り返したい時に使えるコードの書き方です。


簡単な具体例で記載すると、下記ようなものと考えて頂ければ大丈夫です。

[繰り返し処理イメージ]
■九九の結果を表示するプログラム
・1×1、1×2、1×3…1×9までの結果を繰り返し表示する。

なお、今回の内容についても下記の本に掲載されている内容から学んでいきましょう。

繰り返しの基本構造

while文

入力コード

x = int(input('数値を入力してください>>'))
count = 1

while count < 10:
    ans = x * count
    print(f'{x}×{count}のこたえは{ans}です。')
    count += 1

※1行目のinput関数の処理で入力した値は文字列認識される為、int型に変換することで整数とみなされる。

while 条件式:
条件が成立した際の処理
(whileブロック)

※whileの中で繰り返し処理したい内容はインデント(字下げ)して記載することが必要。ジュピターラボの場合はTabキーを使う事でインデントが可能です。

[ポイント]
このコードでは2行目で変数countに1が代入されますので、while文の条件式にある「変数count < 10」に従い変数countの値が1~9の場合に繰り返し処理を実行することになります。

実行結果

数値を入力してください>> 2
2×1のこたえは2です。
2×2のこたえは4です。
2×3のこたえは6です。
2×4のこたえは8です。
2×5のこたえは10です。
2×6のこたえは12です。
2×7のこたえは14です。
2×8のこたえは16です。
2×9のこたえは18です。
<strong>Deviko</strong>
Deviko

入力した数値に1~9を掛けた答えを返してくれている処理と言うことなのね。

<strong>komori</strong>
komori

これを個別に一つずつコードを書いていくとそれだけでもかなりの文字数となりますし、このコードであれば9回で済みますが、回数が数十回や数百、数千などの処理となるとコードを書くことは効率的ではなくなりますので、そういった場合の書き方となります。

状態による繰り返し

入力コード

is_woman = False
count = 0

while is_woman == False:
    count += 1
    print(f'本日は女性限定イベント日です。あなたは{count}人目の来館者です。')
    key = input('あなたは女性ですか?(y/n)>>')
    if key == 'y':
        is_woman = True
print('ようこそいらっしゃいました、ご入館くださいませ。')

[解説]
上記のコードは、ある日のイベントが女性限定だったことを想定して入館チェックをしているプログラムとなります。来館者が男性の場合はwhileブロックを繰り返し実行しますが、来館者が女性であった場合は繰り返し処理を抜けた後の処理を実行します。

[ポイント]
変数is_woman がFalseの間はずっと繰り返すというプログラムとなります。
男性と女性の2択での判定であった場合のフラグ(flag)であり、インプット文での回答が 「 y 」であれば女性となりTrueを、回答が 「 n 」 であればFalseが代入されるなどのbool型がよく使われます。

実行結果

本日は女性限定イベント日です。あなたは1人目の来館者です。
あなたは女性ですか?(y/n)>> n
本日は女性限定イベント日です。あなたは2人目の来館者です。
あなたは女性ですか?(y/n)>> n
本日は女性限定イベント日です。あなたは3人目の来館者です。
あなたは女性ですか?(y/n)>> n
本日は女性限定イベント日です。あなたは4人目の来館者です。
あなたは女性ですか?(y/n)>> n
本日は女性限定イベント日です。あなたは5人目の来館者です。
あなたは女性ですか?(y/n)>> y
ようこそいらっしゃいました、ご入館くださいませ。
<strong>Deviko</strong>
Deviko

女性が来ない限り、変数countは1足されていき人数が増えていくのね。

<strong>komori</strong>
komori

変数countによる条件判定はないため、変数 is_womanがFalseである以上はcountは1が足されていきます。その他のポイントとして、正誤判定や2択判定の場合のbool型を用いる際の変数名ですが、is_〇〇〇とする事が一般的な変数名のつけかたとなります。

繰り返しによるリスト作成

入力コード

count = 0 #カウンタ変数
pokemon_num = int(input('ポケモンの数を入力してください。>>'))#ポケモンの数を入力
score_list = list()#空のリストを作成するコード

while count < pokemon_num:#2行目で入力した数分繰り返す条件式
    count += 1
    score = int(input(f'{count}匹目のポケモンの可愛さポイントを入力 >>'))
    score_list.append(score)
print(score_list)
total = sum(score_list)
print(f'可愛さポイントの合計点は{total}点です。')
print(f'可愛さポイントの平均点は{total//pokemon_num}点です。')

[解説]
このプログラムでは、ポケモンの数分だけ可愛さポイントを入力し、可愛さポイントの合計点平均点を出力するプログラムとなります。
3行目のリストを作るコードは、代入するデータは後のコードで可愛さポイントを代入していきますが、3行目時点では()を書き、空のリスト(箱だけ)を用意したコードの書き方です。

<strong>komori</strong>
komori

リストの中にデータを代入していく時に繰り返し処理は非常によく使われます。

実行結果

ポケモンの数を入力してください。>> 5
1匹目のポケモンの可愛さポイントを入力 >> 10
2匹目のポケモンの可愛さポイントを入力 >> 20
3匹目のポケモンの可愛さポイントを入力 >> 30
4匹目のポケモンの可愛さポイントを入力 >> 40
5匹目のポケモンの可愛さポイントを入力 >> 50
[10, 20, 30, 40, 50]
可愛さポイントの合計点は150点です。
可愛さポイントの平均点は30点です。

[解説]
上の実行結果の場合、1行目のポケモンの数を5と入力したので、1~5までのポケモンの可愛さポイントを入力するプログラムが実行されます。
サンプルでは10、20、30…50と入力していき、順番にリストに値が代入されていき、最後にリストの合計点と平均点が出力されるプログラムとなります。

<strong>Deviko</strong>
Deviko

リストは、データの順序関係があって重複データの代入も出来たのよね。

繰り返しによるリスト要素の利用

入力コード

scores = [10,20,30,40,50]
count = 0
while count < len(scores):
    if scores[count] >= 25:
        print(f'{count + 1}匹目のポケモンの可愛さは合格です。')
    else:
        print(f'{count + 1}匹目のポケモンの可愛さは不合格です。')
    count += 1

[解説]
こちらのコードでは、リスト内の値はまとめて格納していますが、その値が25を以上であれば「合格」、25未満であれば「不合格」を表示する処理をリストscoresの要素分繰り返すプログラムとなっています。

[ポイント]
繰り返しを利用してリストの要素を参照する
カウンタ変数 = 0
while カウンタ変数 < len(リスト):
リスト[カウンタ変数]を使った処理
  カウンタ変数 += 1

<strong>komori</strong>
komori

3行目のコードでリストの中の要素数を返すlen関数を用いて、5回繰り返すことになっていることが分かりますね。

実行結果

1匹目のポケモンの可愛さは不合格です。
2匹目のポケモンの可愛さは不合格です。
3匹目のポケモンの可愛さは合格です。
4匹目のポケモンの可愛さは合格です。
5匹目のポケモンの可愛さは合格です。
<strong>Deviko</strong>
Deviko

入力コードの5行目と7行目に変数count + 1をしないと、0~4匹目のポケモンというメッセージが返ってくるので注意よね。

for文

続いてfor文での繰り返し処理を紹介します。
こちらの方が一般的なコードの書き方となるので、繰り返し処理と言えばfor文を使うとイメージです。
冒頭にも記載しましたが、プログラムは条件分岐と繰り返し処理が多く使われますのでプログラミングをする上では外せない重要な点となります。

for文による繰り返し

入力コード

scores = [20,30,15,50,60]

for data in scores:
    if data >= 25:
        print(f'{scores.index(data)+1}匹目のポケモンの可愛さは合格です。')
    else:
        print(f'{scores.index(data)+1}匹目のポケモンの可愛さは不合格です。')

※for文で使われているdataは変数となります。

for文もwhile文と同様に繰り返しおこないたい処理をインデントして記載します。
上記コードでリストscoresは5つの要素があるので、3行目のfor文で5回繰り返すといった意味となります。
for 変数 in リスト:
繰り返し処理

<strong>Deviko</strong>
Deviko

文字を表示するコードで{scores.index(data)+1}が複雑な書き方になっているのはなぜ?

<strong>komori</strong>
komori

直前のwhile文の説明にある最後のコードと同じ処理となるfor文コードを書いたので、scores.index(data)を使ってリストscoresの何番目の値であるかを返しています。ただし、scoresの要素は0~4番となるので、最後に+1をすることで実現しています。
※変数dataには1行目に書かれている20、30、15…の順番に値が代入されています。

実行結果

1匹目のポケモンの可愛さは不合格です。
2匹目のポケモンの可愛さは合格です。
3匹目のポケモンの可愛さは不合格です。
4匹目のポケモンの可愛さは合格です。
5匹目のポケモンの可愛さは合格です。

for文による決まった回数の繰り返し

入力コード

for num in range(3):
    print('ポケモンはみんなかわいい。')

今度は決まった回数がある場合のfor文で繰り返し処理のコードです。range関数を用いて繰り返す回数を指定しています。

for 変数 in range(n):
繰り返し処理

※nは繰り返す回数を入力する。

実行結果

ポケモンはみんなかわいい。
ポケモンはみんなかわいい。
ポケモンはみんなかわいい。

while文とfor文の使い分けに

while文とfor文の使い分けについては、下記のような場合と考えておきましょう。
・繰り返しの回数の目処が立たない時:while文
・繰り返しの回数の目処が立つ時:for文

例えば、サイコロを振って出目が6になるまで繰り返す場合はwhile文を使ってコードを書き、3回サイコロを振って出目の合計を返すプログラムの場合は、for文でコードを書く方といったイメージです。

入力コード

#サイコロの出目が6になるまで処理を繰り返す
import random#ランダム関数を使うための準備コード
is_dice = True

while is_dice == True:#Trueの間繰り返す
    num = random.randint(1,6)#数値1~6をランダムで生成するコード
    print(f'サイコロの目は{num}です。')
    if num == 6:
        is_dice = False
print(f'{num}がでましたので処理を終了します。')

実行結果

サイコロの目は3です。
サイコロの目は2です。
サイコロの目は1です。
サイコロの目は2です。
サイコロの目は1です。
サイコロの目は4です。
サイコロの目は5です。
サイコロの目は5です。
サイコロの目は6です。
6がでましたので処理を終了します。
<strong>Deviko</strong>
Deviko

サイコロの出目が6になる回数は目処が立たないから、while文を使って書いてるってわけね。

入力コード

#サイコロを3回振り、出目と合計を計算し表示する。
import random#ランダム関数を使うための準備
total = 0

for count in range(3):
    count += 1
    num = random.randint(1,6)#数値1~6をランダムで生成する
    total = total + num
    print(f'サイコロは{count}回目の出目は{num}でこれまでの合計は{total}です。')

実行結果

サイコロは1回目の出目は4でこれまでの合計は4です。
サイコロは2回目の出目は6でこれまでの合計は10です。
サイコロは3回目の出目は2でこれまでの合計は12です。

繰り返し処理の制御

繰り返しの強制終了

繰り返しを強制終了するコードはbreak文となります。
下記にサンプルコードを記載しますのでご覧ください。
break文は繰り返し処理自体を中断します。

入力コード

scores = [10,20,30,40,50,60,70,80,90,100]#リスト
n = 5 #抽出数
samples = list()#スコアを格納するリスト

for data in scores:
    if 20 <= data < 80:
        samples.append(data)
        if len(samples) == n:
            break#強制終了する際のコード
print(f'抽出されたリスト内の値は{samples}です。')   

[解説]
2行目の抽出数である変数nの5は、リストsamplesの要素数の条件を指定しています(8行目)。つまり、1行目のリストscoresの値から5つの値を取り出すといったコードです。
更に、5行目の繰り返し処理にて20以上80未満の数値を取り出す条件を指定しているため、リストscoresの値から数値の範囲に当てはまる値を5つ取り出し、リストsmplesに格納するプログラムとなります。

実行結果

抽出されたリスト内の値は[20, 30, 40, 50, 60]です。
<strong>komori</strong>
komori

リストsamplesに取り出せる条件1の20以上80未満では、20,30,40,50,60,70の6つの値となりますが、条件2のリストsamplesの要素数が5になった時点で終了する。といったbreakコードにより70は除外されています。

繰り返しのスキップ

繰り返しをスキップするコードはcontinue文となります。
下記にサンプルコードを記載しますのでご覧ください。
continue文は現在の回数のみ中断して、次の回の処理に進みます。

入力コード

scores = [10,20,'返事がない',40,50,'言いたくない',70,80,90,100]#リスト
samples = list()#スコアから抜き出した値を格納する空のリスト

for data in scores:
    if not isinstance(data, int):#整数型の値以外は除外する条件
        continue#スキップする際のコード
    if data < 20 or data >= 90:#20未満は除外または、90以上は除外の条件
        continue#スキップする際のコード
    samples.append(data)
print(f'抽出されたリスト内の値は{samples}です。')


isinstance(データ,データ型)
※データとデータ型が一致するとTrueが返る。
※データ型はint型、str型,bool型などが使用可能。

[解説]
1行目のリストscoresから特定の値を抜き出し、リストsumplesに代入していく処理ですが、条件として整数型で無かった場合は処理をスキップとなります。(4行目)
また、整数型であったとして20未満と90以上の値であった場合もスキップとなります。(6行目)

実行結果

抽出されたリスト内の値は[20, 40, 50, 70, 80]です。

まとめ

繰り返し処理おさらい

[繰り返し]
・while文は、条件に従ってwhileブロック内の処理を繰り返し実行することができる。
・while文は、回数の目処が立たない繰り返しの処理のコードとして適している。
・for文は、コレクションが持つ要素数の回数だけ処理をすることができる。
・for文は、データの集まりを順に参照する繰り返し、一定回数の繰り返しに適している。

[繰り返しの中断]
・break文は、繰り返しのを強制的に終了する。
・continue文はその回のループを終了し、次の回を継続する。

[繰り返しのヒント]
・永久におわることのない繰り返し処理を無限ループと呼ぶ。
・range関数で定数回の繰り返し処理を作成することができる。
・繰り返し処理によるコレクション操作はプログラムとしてよく使われる。
・繰り返しと分岐の組み合わせで、実践的なコードを記述することができる。

さいごに

さいごまでお読み頂きありがとうございました。

今回説明した繰り返し処理は、条件分岐処理とともにプログラムの醍醐味と言えると思います。
人の手で作業することを自動化することで、労力や時間的なコスト削減するための便利なものとしてプログラムを捉えるならその理由は明らかだと思います。

エキシビジョン

ここまでの条件分岐と繰り返し処理を用いて簡単なアプリを作ってみます。

以下は、コンピュータとじゃんけんを3回勝負する簡単なアプリとなり、ユーザーインターフェースがCUIとなりますが、これも立派なアプリケーションとなります。

入力コード

#コンピュータとじゃんけん3回勝負アプリ
import random#ランダム関数
dic2 = {1:'グー',2:'チョキ',3:'パー'}

print('これからじゃんけんでコンピュータと3回勝負をしていきます。')
for count in range(3):#3回繰り返すコード
    dkeys = random.randint(1,3)#ランダム関数で1~3の数値を生成するコード
    cpu = dic2[dkeys]#ランダム数値要素と紐づく値をdicより参照
    user = input('数字で入力(1:グー,2:チョキ,3:パー)>>')

    if user.isdigit():
        if 0 < int(user) <= 3:#3以下の数値の場合の処理
            user2 = dic2[int(user)]
            print(f'あなたは{user2}で、コンピュータは{cpu}です。')
        else:
            print('無効な値が入力されました。最初からやり直してください。')
            break
    else:
        print('無効な値が入力されました。最初からやり直してください。')
        break

[解説]
まずは、グー、チョキ、パーをコレクションのディクショナリdic2で定義しています。
コンピュータとユーザーの出す手を、それぞれ下記のように処理して生成しています。

繰り返しについては「for count in range(3)」で3回繰り返すと指定しています。

①コンピュータ:ランダム関数を用いて1~3の数値を変数dkeysに代入
dkeysに1から3の数値が代入されるため、コレクションdic2からアイテムを参照するキーとして使用しています。
cpu = dic2[dkeys]

②ユーザ:input関数で選択した数値を変数userに代入
input関数にて取得した数値を変数userに代入し、if文で条件判定処理を実行している。

・判定式1:if user.isdigit():
入力された値(user)が整数であるかを判定をし、True or False で返ってきます。

・判定式2:if 0 < int(user) <= 3:
入力された値(user)が1~3の範囲内であるか判定しています。※input関数で入力した値は文字列として返ってくるのでint関数を使って整数に変換した後に0より大きく3以下であるかを判定しています。

判定式1と2ともにTrueとなる場合は、じゃんけんの結果を出力します。
しかし、何れかの判定式でFalseが返ってきた場合は「無効な値が入力されました。…」をエラー表示して、繰り返し処理を終了します。

実行結果

これからじゃんけんでコンピュータと3回勝負をしていきます。
数字で入力(1:グー,2:チョキ,3:パー)>> 1
あなたはグーで、コンピュータはパーです。
数字で入力(1:グー,2:チョキ,3:パー)>> 2
あなたはチョキで、コンピュータはチョキです。
数字で入力(1:グー,2:チョキ,3:パー)>> 3
あなたはパーで、コンピュータはパーです。

ユーザーが入力した値に問題がなく、正常終了した場合の実行結果。

これからじゃんけんでコンピュータと3回勝負をしていきます。
数字で入力(1:グー,2:チョキ,3:パー)>> 2
あなたはチョキで、コンピュータはパーです。
数字で入力(1:グー,2:チョキ,3:パー)>> グー
無効な値が入力されました。最初からやり直してください。

2回目のユーザー入力で数値ではなく、文字列”グー”と入力された場合のエラー終了。

<strong>Deviko</strong>
Deviko

数値の入力ではなくて、文字を入力してしまった場合の事も想定しているのね。


次回は関数の書き方について紹介する予定です。

コメント

タイトルとURLをコピーしました