質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

1626閲覧

任意の数に付いて割れる数を表示するコード

SenaK

総合スコア10

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/02/08 22:56

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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<=numberrange(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ではない、最小の xnumberを割り切れたとき、その商を y とすれば、number自体よりも小さい約数のうち最大のものが y になる。ゆえに、xy に等しくなったときループを抜けることができる。

ということになります。上記を追加したコードが以下です。

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
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SenaK

2020/02/08 23:51

ありがとうございます!解決致しました。
jun68ykt

2020/02/08 23:55

どういたしまして。 > 解決致しました。 とのことでよかったです????
guest

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

can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SenaK

2020/02/08 23:52

回答ありがとうございます!解決致しました。
guest

0

多分試行錯誤の結果だと思いますが、提示されたコードは色々間違っています。
ただ、今回の一番大きな問題は、for in の使用方法が間違っていることなのでそこだけ説明します。

エラー文は読めているようですが、そういった場合はまず公式ドキュメントを参照してください。

for 文

式リストは一度だけ評価されます。その結果はイテラブルオブジェクトにならなければなりません。

ただ、 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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SenaK

2020/02/08 23:52

参考にさせていただきます!解決致しました。
guest

0

div.py

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 7if __name__=="__main__": 8 divisor()

実行例

イメージ説明

投稿2020/02/08 23:08

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問