こんにちは。ナミレリです。今回はPythonでループ処理をするときに使うwhile文を紹介します。
- M2 MacBook Air 13.6 インチ
- macOS Ventura 13.0
- pyenv 2.3.4
- Python 3.10.6
目次
for文との違い
Pythonではforとwhileでループ処理を行います。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点がポイントです。
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 BuzzやBuzzとも呼ばれる)は
英語圏で長距離ドライブ中や飲み会の時に行われる言葉遊びである。プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。
https://ja.wikipedia.org/wiki/Fizz_Buzz
次のプレイヤーは直前のプレイヤーの発言した数字に1を足した数字を発言していく。
ただし、3の倍数の場合は「Fizz」(Bizz Buzzの場合は「Bizz」)、5の倍数の場合は「Buzz」、
3の倍数かつ5の倍数の場合(すなわち15の倍数の場合)は「Fizz Buzz」
(Bizz Buzzの場合は「Bizz 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 = 1でiの初期値を1に設定し、whileの条件でiが100以下であればiを表示します。iを表示した後はiを1増やします。
for文で1から100まで順番に数字を表示する
次にfor文では「1から100まで順番に数字を表示する」にはどうしたらよいでしょうか。
for文で1から100まで順番に数字を表示する
>>> for i in range(1, 101):
... print(i)
...
繰り返し変数をiとして、繰り返しを指定するイテラブルオブジェクトにrange関数で1から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の倍数でもない」ことは、
https://ja.wikipedia.org/wiki/Fizz_Buzz
「ある自然数と15が互いに素である」ことと同義である。
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"}ですが、辞書オブジェクトです。辞書オブジェクトとはKeyとValueという2つの値をペアで保持するデータ型です。辞書オブジェクトは波括弧{}を使い作成し、KeyとValueの区切りには:を置きます。
この例では下の表の辞書オブジェクトを作成しています。
Key | Value |
---|---|
3 | Fizz |
5 | Buzz |
15 | FizzBuzz |
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()関数は引数に指定した整数の最大公約数を返すので、この場合はiと15の最大公約数を返します。
gcd関数の簡単な例です。(9と15の最大公約数を求めています)
>>> import math
>>> math.gcd(9, 15)
3
mothモジュールを使って15との最大公約数を用いた方法のまとめ
これまでで説明した通り、dict.get(math.gcd(i, 15), i)は、iと15の最大公約数を求めてその数をdictのKeyとしてValueを取得しますが、Keyが存在しなければiとする。という意味になります。
for文のループでiが9だとして考えてみます。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万冊以上が読み放題。お好きな端末で利用可能です。