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

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

ただいまの
回答率

90.75%

  • Python 3.x

    5286questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

素数を判定するプログラム

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,317

YutaMoris.

score 1

以下のプログラムで最初の出力が2になる理由がわかりません。
最初は2%2 == 0になるから出力されないのではないのでしょうか。

def get_primes(x=2):
while True:
for i in range (2,x):
if x % i == 0:
break
else:
yield x
x += 1

i = get_primes()
for c in range(10):
print(next(i))


2
3
5
7
11
13
17
19
23
29

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

正しくインデントした場合、こうなるのですよね?

def get_primes(x=2):
    while True:
        for i in range (2,x):
            if x % i == 0:
                 break
        else:
             yield x
        x += 1

i = get_primes()
for c in range(10):
    print(next(i))

既にsuyamaさんが指摘されているとおり、Pythonではインデントが重要な意味を持ちます。
インデントが崩れないよう注意して投稿してください。分からなければ聞いてください。


rangeの挙動について勘違いされているのかと思います。

>>> for i in range(2, 2):
...     print(i)
...
>>> for i in range(2, 3):
...     print(i)
...
2

class range(start, stop[, step])
(中略)
step が正の場合、range r の内容は式 r[i] = start + step*i で決定されます。ここで、 i >= 0 かつ r[i] < stop です。

リファレンスより引用、太字は引用者。
つまり、ご提示のコードは、自分自身による剰余算が発生しないよう工夫されています。


print関数を適宜埋め込んで試してみるといいかと思います。

def get_primes(x=2):
    while True:
        print('-' * 64)
        print('割られる数:', x)
        for i in range (2,x):
            print('割る数:', i)
            if x % i == 0:
                 print(i, '割り切れた')
                 break
        else:
             yield x
        x += 1

i = get_primes()
for c in range(10):
    print(next(i), 'は素数')

"""実行結果
----------------------------------------------------------------
割られる数: 2
2 は素数
----------------------------------------------------------------
割られる数: 3
割る数: 2
3 は素数
----------------------------------------------------------------
割られる数: 4
割る数: 2
2 割り切れた
----------------------------------------------------------------
割られる数: 5
割る数: 2
割る数: 3
割る数: 4
5 は素数
----------------------------------------------------------------
割られる数: 6
割る数: 2
2 割り切れた
----------------------------------------------------------------
割られる数: 7
割る数: 2
割る数: 3
割る数: 4
割る数: 5
割る数: 6
7 は素数
----------------------------------------------------------------

以下続く
"""

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

Pythonのコードはインデントが重要な意味を持ちますので、<code>で挿入される"コードを入力"で必ず囲むようにしてください。
動作を確認し、元のコードは下記であると推測しています。

def get_primes(x=2):
  while True:
    for i in range (2,x):
      if x % i == 0:
        break
    else:
      yield x
    x += 1

i = get_primes()
for c in range(10):
   print(next(i))

`

最初は2%2 == 0になるから出力されないのではないのでしょうか。

動作としては逆で、割った余りが0であれば素数として判定されてyieldでデータとして渡され出力されます。
xの値は初期値として引数に指定された以降は無限ループで増えていくため、同じ数値が素数として出てくることはありません。


追記:

動作を誤って認識していました。
割った余りが0であれば合成数ということですね。
2が出力される理由は、LouiS0616さんのご回答の通りです。
誤った回答をしてしまい申し訳ありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/09 11:13

    素数は、約数をちょうど2つしか持たない(1と自分自身)自然数を指すので、range(2, x)の範囲では割り切れませんよ。
    また、breakが実行されたときelse節は通過しません。
    > 最初のスイート内で break 文が実行されると、 else 節のスイートを実行することなくループを終了します。
    https://docs.python.jp/3/reference/compound_stmts.html#the-for-statement

    キャンセル

  • 2017/10/09 11:19 編集

    ご指摘ありがとうございます。
    コードの動作を勘違いしていました。
    インデントを直す方に注力してしまって、肝心の素数判定方法を逆に取り違えてしまっていました。
    break時はforのelseを実行しない点は、自分では使うことがなかったので把握していませんでした。大変参考になります。

    キャンセル

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    5286questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。