Python3 を学んでいる初心者です。
ユーザーに数を入力してもらい、その数を余りなしで割り切ることができる数字を全て表示するプログラムを作ろうと思い、以下のコードを書きました。
Python
1def divisor(): 2 number = int(input("Number:")) 3 x=0 4 for x in x<=number: 5 if number%x==0: 6 print(x) 7 else: 8 break 9 x = x+1 10 11if __name__=="__main__": 12 divisor() 13
このコードが動かない理由を教えてくださると幸いです。エラー文には'bool' object is not iterableとあり、「True/Falseで結果が出るようなものをfor文など繰り返しの発生するものに入れてはならない」、と解釈しているのですが、どこが原因なのか不明です。初歩的な質問ですが、どうぞよろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
こんにちは
エラー文には'bool' object is not iterableとあり、「True/Falseで結果が出るようなものをfor文など繰り返しの発生するものに入れてはならない」、と解釈しているのですが、どこが原因なのか不明です。
その解釈自体は間違っていないです。具体的なエラー箇所としては
for x in x<=number:
の部分で、 in
の後に、 x<=number
があることです。 x<=number
が、SenaKさんの解釈でいうところの
True/Falseで結果が出るようなもの
に相当します。コードの意図からすると、 x
を 0以上number
以下でループさせたいのだと思いますので、そのようにするには、以下の3点を修正します。
(1) x=0
は不要なので削除
(2) x<=number
を range(0, number+1)
に修正
(3) 上記(2)の修正によって、x = x+1
が不要になるので削除
ご質問に挙げられているコードを、上記の3点について修正すると divisor()
は以下になります。
python3
1def divisor(): 2 number = int(input("Number:")) 3 for x in range(0, number+1): 4 if number % x == 0: 5 print(x) 6 else: 7 break
しかし、上記だと、今度は ZeroDivisionError: integer division or modulo by zero
というエラーが発生すると思います。これは、number
を 0始まりにしているために、ループの初回で number
を 0 で割ることになってしまうためのエラーです。
作成したいプログラムは、入力された整数値の約数を表示させたいということだと思いますが、0は(通常、)約数になりません。以下は wikipedia 約数 からの引用です。
整数 a ≠ 0 が N の約数であるとは、「ある整数 b をとると N = ab が成立することである」であるが、 条件「a ≠ 0」を外すこともある。このときは、N = 0 のときに限り 0 も約数になる。
なので、ここでは 0 を約数から除外することにして、 x
を 1始まりにします。それには、
range(0, number+1)
を
range(1, number+1)
とします。この修正で以下のようになります。
python3
1def divisor(): 2 number = int(input("Number:")) 3 for x in range(1, number+1): 4 if number % x == 0: 5 print(x) 6 else: 7 break
ところが、上記だと、 たとえば 12
を入力すると、 1, 2, 3, 4 まで表示されて、 6 が出力されないです。これの原因としては、else:
のときに break
してしまっているからです。これを除去して以下になります。
python3
1def divisor(): 2 number = int(input("Number:")) 3 for x in range(1, number+1): 4 if number % x == 0: 5 print(x)
これでとりあえず、(少なくとも正の整数を入力されたときは)意図通りの出力が得られると思いますが、最後にもう一点、改善の余地があります。たとえば12
が入力されたとき、上記のコードだと、12回ループしてx
は1以上12以下の値をとりますが、入力されたその数自体が約数になることは自明なのと、その数自体以外の約数は、その数の半分以下であるので、以下のようにしてループ回数を半分に出来ます。
python3
1def divisor(): 2 number = int(input("Number:")) 3 for x in range(1, number // 2 + 1): 4 if number % x == 0: 5 print(x) 6 print(number)
上記だと、たとえば 12 が入力されたときは、x
が1以上6以下までのループになり、15が入力されたときは、1以上7以下までのループになります。
以上、参考になれば幸いです。
補足
蛇足ですが、さらにループの回数を少なくする改善案を挙げておきます。
たとえば、105 が入力されたとき、 1 よりも大きい最小の約数は 3 です。105 を 3 で割った商は 35 ですが、この 35 が、 105 それ自体よりも小さい約数としては最大になります。これを一般化してコードにするとすれば、
- 1ではない、最小の
x
でnumber
を割り切れたとき、その商をy
とすれば、number
自体よりも小さい約数のうち最大のものがy
になる。ゆえに、x
がy
に等しくなったときループを抜けることができる。
ということになります。上記を追加したコードが以下です。
python3
1def divisor(): 2 number = int(input("Number:")) 3 y = 0 4 for x in range(1, number // 2 + 1): 5 if number % x == 0: 6 print(x) 7 if y == 0 and x > 1: 8 y = number // x 9 if x == y: 10 break 11 print(number)
上記だと、たとえば 105 が入力されると、 x
が 35 になったときに break でループから抜けます。この y
による break がない、ひとつ前のコードだと、x
が 52 になるまでループします。
投稿2020/02/08 23:50
編集2020/02/09 02:10総合スコア9058
0
まず、コマンドプロンプトなどのターミナル上でコードを実行してエラーが発生すると
PlainText
1Traceback (most recent call last): 2 File "~\hoge.py", line 13, in <module> 3 divisor() 4 File "~\hoge.py", line 5, in divisor 5 for x in x<=number: 6TypeError: 'bool' object is not iterable
というようにどの行でエラーが発生したかが分かります。
ここで問題なのはfor x in x<=number:
のx<=number
の部分です。
この部分では数値の大小比較をしていますが、その結果はbool
値になります。
bool
値はiterable
ではない、すなわちfor
文で走査できないため提示エラーが発生するのです。
修正方法についてはkatoy
さんの回答コードの通りでよいかと思います。
投稿2020/02/08 23:22
総合スコア38341
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
多分試行錯誤の結果だと思いますが、提示されたコードは色々間違っています。
ただ、今回の一番大きな問題は、for in の使用方法が間違っていることなのでそこだけ説明します。
エラー文は読めているようですが、そういった場合はまず公式ドキュメントを参照してください。
式リストは一度だけ評価されます。その結果はイテラブルオブジェクトにならなければなりません。
ただ、 python の日本語ドキュメントは非常にわかりにくいです。
「よくわかんねぇ」と思ったら、英語版を読んでください。
The expression list is evaluated once; it should yield an iterable object.
ようするに expression list が iterable object でなければならないのに、今回は
x<=number
と bool が返ってくるモノになっています。
ここを適切にすると、意図したコードに近づきます。
(まぁ、回答でちゃってますけどw)
投稿2020/02/08 23:14
退会済みユーザー
総合スコア0
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/08 23:51
2020/02/08 23:55