【Python】while文でのループ処理の基本(for文との違いやFizz Buzz問題も)

9 min

こんにちは。ナミレリです。今回はPythonでループ処理をするときに使うwhile文を紹介します。

この記事のMac環境
  • M2 MacBook Air 13.6 インチ
  • macOS Ventura 13.0
  • pyenv 2.3.4
  • Python 3.10.6
Parallels Desktop 20 for Macの無料トライアル もありますので、ぜひダウンロードして試してみてください。M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。
NEW Parallels Desktop 20 for Mac

Parallels Desktop 20 for Macは、M1/M2/M3のMac上で快適にMacやUbuntu、Windowsが動作します。

14日間の無料トライアルもありますので、ぜひダウンロードして試してみてください。

for文との違い

Pythonではforwhileでループ処理を行います。for文については下の記事で紹介しています。まだの方はぜひ確認ください。

for文との違いですが、forは繰り返し変数を置き、inで指定するイテラブルオブジェクトに対して繰り返し処理を行います。whileは繰り返し変数や対象となるイテラブルオブジェクトを指定する必要がありません

for文の例です。繰り返し変数と繰り返しの対象となるイテラブルオブジェクトを指定します。


>>> numbers = [0, 1, 2, 3, 4, 5]
>>> for num in numbers:
...     print(num)
... 
0
1
2
3
4
5

こちらはwhile文の例です。指定した条件が真(True)であればループ処理を続けます。


>>> num = 0
>>> while num <= 5:
...     print(num)
...     num+=1
... 
0
1
2
3
4
5

上のようにwhile文は条件を指定しその条件が偽(False)になるとループを抜けます。上の例では num <= 5が条件ですね。当然ですが条件が真(True)であればループ処理を続けます。

Pythonでのwhile文とfor文の違いをまとめると下記の3点がポイントです。

while文は指定した条件が偽(False)となればループを抜ける

while文は指定した条件が真(True)であればループ処理を続け

for文は繰り返し変数を置き、inで指定するに対して繰り返し処理を行う

Pythonでプロのコードを書くための考え方やテクニックを学びたい方におすすめ書籍です。
VTuberサプーが教える! Python 初心者のコード/プロのコード

Pythonのwhile文とは

上のfor文との違いでも説明しましたが、Pythonではfor文とwhile文でループ処理を行うことができます。while文のループは指定した条件が真(True)であればループ処理を続けます。指定した条件を満たし続け、偽(False)にならず永遠に終わらないループ処理のことを、無限ループといいます。無限ループになってしまった時はcontrol+cで強制終了します。

上のwhile文の例の条件を num <= 5から num >= 0すると無限ループとなります。

while文の無限ループ(control+cで強制終了してください)


>>> num = 0
>>> while num >= 0:
...     print(num)
...     num+=1
... 
0
1
2
.
.
.
1011316
1011317
1011318

この例ではwhileの条件がnum >= 0(0以上)となっています。print文でnumを表示した後にnum+1でインクリメントします。0より小さい数字にならないので、条件は常に真(True)となり永遠とループ処理が行われてしまいます。

Pythonのwhile文の構文

Pythonのwhile文は下に記載した構文となります。whileの後に条件を指定します。2行目にはTabでインデントして条件が真の場合に行う処理を書きます。

whileスペース条件:
Tab条件が真の場合に行う処理

PythonでFizz Buzzをやってみる

それではwhile文とfor文でFizz Buzzをやってみます。Fizz Buzzとは英語圏での簡単なパーティーゲームです。(詳しくはhttps://ja.wikipedia.org/wiki/Fizz_Buzz

Fizz Buzz(フィズ・バズ、Bizz BuzzBuzzとも呼ばれる)は
英語圏で長距離ドライブ中や飲み会の時に行われる言葉遊びである。

プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。
次のプレイヤーは直前のプレイヤーの発言した数字に1を足した数字を発言していく。
ただし、3の倍数の場合は「Fizz」(Bizz Buzzの場合は「Bizz」)、5の倍数の場合は「Buzz」、
3の倍数かつ5の倍数の場合(すなわち15の倍数の場合)は「Fizz Buzz
(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。
発言を間違えた者や、ためらった者は脱落となる。

https://ja.wikipedia.org/wiki/Fizz_Buzz

Fizz Buzzの問題をまとめると下記のようになります。

・【その1】1から100まで順番に数字を表示する
・【その2】3と5の両方で割り切れるときは「FizzBuzz」と表示する
・【その3】3で割り切れるときは「Fizz」と表示する
・【その4】5で割り切れるときは「Buzz」と表示する

出力イメージは下記のようになります。


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz

それではひとつひとつやってみましょう。

ひとつひとつ考えてみる:【その1】1から100まで順番に数字を表示する

まず「1から100まで順番に数字を表示する」にはどうしたらよいでしょうか。

while文で1から100まで順番に数字を表示する

while文で1から100まで順番に数字を表示する


>>> i = 1
>>> while i <= 100:
...     print(i)
...     i += 1
... 

i = 1iの初期値を1に設定し、whileの条件でiが100以下であればiを表示します。iを表示した後はiを1増やします。

+=は累算代入演算子でi += 1i = i +1と同じことです。

for文で1から100まで順番に数字を表示する

次にfor文では「1から100まで順番に数字を表示する」にはどうしたらよいでしょうか。

for文で1から100まで順番に数字を表示する


>>> for i in range(1, 101):
...     print(i)
... 

繰り返し変数をiとして、繰り返しを指定するイテラブルオブジェクトにrange関数で1から101までを指定しています。

range(start, end)で、start <= i < endstart以上、end未満)となるため、endには101を指定します。

while文でもfor文でも1から100まで順番に数字を表示することができたと思います。次は3と5の両方で割り切れるときは「FizzBuzz」と表示する、をやってみましょう。

ひとつひとつ考えてみる:【その2】3と5の両方で割り切れるときは「FizzBuzz」と表示する

次に「3と5の両方で割り切れるときは「FizzBuzz」と表示する」にはどうしたらよいでしょうか。

iを3で割った余りが0で、かつ5で割った余りも0であれば「FizzBuzz」と表示してみます。

while文で3と5の両方で割り切れるときは「FizzBuzz」と表示する

while文で3と5の両方で割り切れるときは「FizzBuzz」と表示する


>>> i = 1
>>> while i <= 100:
...     if i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     else:
...         print(i)
...     i += 1
... 

for文で3と5の両方で割り切れるときは「FizzBuzz」と表示する

for文で3と5の両方で割り切れるときは「FizzBuzz」と表示する


>>> for i in range(1, 101):
...     if  i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     else:
...         print(i)
... 

while文でもfor文でもif文を使い3と5の両方で割り切れるときは「FizzBuzz」と表示することができました。次は3で割り切れるときは「Fizz」と表示する、をやってみましょう。

ひとつひとつ考えてみる:【その3】3で割り切れるときは「Fizz」と表示する

次に「3で割り切れるときは「Fizz」と表示する」にはどうしたらよいでしょうか。

elifの条件にiを3で割った余りが0であれば「Fizz」と表示してみます。

while文で3で割り切れるときは「Fizz」と表示する

while文で3で割り切れるときは「Fizz」と表示する


>>> i = 1
>>> while i <= 100:
...     if  i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     elif i % 3 == 0:
...         print("Fizz")
...     else:
...         print(i)
...     i += 1

for文で3で割り切れるときは「Fizz」と表示する

for文で3で割り切れるときは「Fizz」と表示する


>>> for i in range(1, 101):
...     if  i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     elif i % 3 == 0:
...         print("Fizz")
...     else:
...         print(i)
... 

while文でもfor文でもelif文を3で割り切れるときは「Fizz」と表示することができました。次は最後の5で割り切れるときは「Buzz」と表示する、をやってみますが同じようにelifを使います。

ひとつひとつ考えてみる:【その4】5で割り切れるときは「Buzz」と表示する

次に「5で割り切れるときは「Buzz」と表示する」にはどうしたらよいでしょうか。

さらにelifを追加してその条件にiを5で割った余りが0であれば「Buzz」と表示してみます。

while文で5で割り切れるときは「Buzz」と表示する

while文で5で割り切れるときは「Buzz」と表示する


>>> i = 1
>>> while i <= 100:
...     if  i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     elif i % 3 == 0:
...         print("Fizz")
...     elif i % 5 == 0:
...         print("Buzz")
...     else:
...         print(i)
...     i += 1

for文で5で割り切れるときは「Buzz」と表示する

for文で5で割り切れるときは「Buzz」と表示する


>>> for i in range(1, 101):
...     if  i % 3 == 0 and i % 5 == 0:
...         print("FizzBuzz")
...     elif i % 3 == 0:
...         print("Fizz")
...     elif i % 5 == 0:
...         print("Buzz")
...     else:
...         print(i)
... 

これでFizz BuzzをPythonで実装することができました。

PythonでFizz Buzzを15との最大公約数を用いた方法でやってみる

これまでのPythonでのFizz Buzzのやり方は最も標準的なやり方ですが、その他の様々な方法の1つにこちらにも記載がありますが、「15との最大公約数を用いた方法」がありますので紹介します。

剰余演算を用いない方法としては、例えば15との最大公約数を用いた方法が考えられる。

「ある自然数が3の倍数であるが、5の倍数ではない」ことは、
「ある自然数と15の最大公約数が3である」ことと同義である。

「ある自然数が5の倍数であるが、3の倍数ではない」ことは、
「ある自然数と15の最大公約数が5である」ことと同義である。

「ある自然数が15の倍数である」ことは、
「ある自然数と15の最大公約数が15である」ことと同義である。

「ある自然数が3の倍数でも5の倍数でもない」ことは、
「ある自然数と15が互いに素である」ことと同義である。

https://ja.wikipedia.org/wiki/Fizz_Buzz

mathモジュールを使って15との最大公約数を用いた方法は下記のようになります。

mothモジュールを使って15との最大公約数を用いた方法


import math

dict = {3: "Fizz", 5: "Buzz", 15: "FizzBuzz"}
for i in range(1, 101):
    print(dict.get(math.gcd(i, 15), i))

mathモジュールとは?

最初にmathモジュールをインポートします。mathモジュールはPython標準で用意されている数学計算用の関数を集めたモジュールです。今回はmathモジュールの最大公約数を求めるgcd関数を使うためにインポートします。


import math

gcdは「greatest common divisor」の略です。

Pythonの辞書オブジェクトとは?

次のdict = {3: "Fizz", 5: "Buzz", 15: "FizzBuzz"}ですが、辞書オブジェクトです。辞書オブジェクトとはKeyValueという2つの値をペアで保持するデータ型です。辞書オブジェクトは波括弧{}を使い作成し、KeyValueの区切りには:を置きます。

この例では下の表の辞書オブジェクトを作成しています。

KeyValue
3Fizz
5Buzz
15FizzBuzz

get()メソッドを使ってKeyからValueを取得する

次のdict.get(math.gcd(i, 15), i)は、get()メソッドを使ってKeyからValueを取得しています。例えば、dict.get(5)とするとBuzzを取得できます。


>>> import math
>>> dict = {3: "Fizz", 5: "Buzz", 15: "FizzBuzz"}
>>> dict.get(5)
'Buzz'

また、Keyが存在しない場合にエラーを発生させずに任意の値を取得することができます。やってみましょう。get()メソッドの第二引数に任意の値を指定します。


>>> import math
>>> dict = {3: "Fizz", 5: "Buzz", 15: "FizzBuzz"}
>>> dict.get(4)

>>> import math
>>> dict = {3: "Fizz", 5: "Buzz", 15: "FizzBuzz"}
>>> dict.get(4, 'TEST')
'TEST'

mathモジュールのgcd()関数:最大公約数を求める

math.gcd(i, 15)この部分は、mathモジュールのgcd()関数を使って最大公約数を求めています。gcd()関数は引数に指定した整数の最大公約数を返すので、この場合はi15の最大公約数を返します。

gcd関数の簡単な例です。(9と15の最大公約数を求めています)


>>> import math
>>> math.gcd(9, 15)
3

mothモジュールを使って15との最大公約数を用いた方法のまとめ

これまでで説明した通り、dict.get(math.gcd(i, 15), i)は、i15の最大公約数を求めてその数をdictKeyとしてValueを取得しますが、Keyが存在しなければiとする。という意味になります。

for文のループでi9だとして考えてみます。9と15の最大公約数は3となり、dictからKeyが3であるValueを取得します。ValueはFizzです。

最後に

最後まで読んでいただきありがとうございます。今回の「【Python】while文でのループ処理の基本(for文との違いやFizz Buzz問題も)」はいかがでしたでしょうか。

while文やfor文でのループ処理(制御処理)は使用頻度が高いので、どちらでも書けるようにぜひマスターしてください。

Pythonはプログラム言語としてシンプルに作られていてとても覚えやすい言語です。業務で本格的に使うこともできす。データサイエンスや人工知能などのワクワクする分野ではほとんどPythonが使われているようです。MacでPythonの開発環境を整えて、その環境でPythonを学び勉強することはとても楽しいです。この記事が少しでもお役に立つと幸いです。

MacやLinux、Pythonなど技術系のkindle本も豊富にあります。詳しくはこちらから。

Amazonの電子書籍読み放題サービス「Kindle Unlimited」でプライム会員を対象に、最初の3か月間を無料体験できるキャンペーンを実施中。マンガ、小説、ビジネス書、雑誌など500万冊から、好きな本を何冊でも読めるキャンペーンです。

初めてkindle unlimited 読み放題をご利用の方は30日間の無料で体験できます。
期間終了後は月額980円で、いつでもキャンセルできます。
200万冊以上が読み放題。お好きな端末で利用可能です。

定番おすすめ記事

Pythonの基本構文など最初に覚えておきたいPythonの初心者向け記事です。

カテゴリー:
関連記事