- 締切済み
for文内のelseに飛ぶ理由
pythonの次のようなコードがあり、 for文: for文: else: となったとき、いきなりelse内に飛ぶ挙動の説明をお願いします #--コード-- #UTF-8 for n in range(2, 5): for x in range(2, n): if n % x == 0: print('xは ' + str(x)) print('nは ' + str(n) + ' は割り切れる') break else: print(n,' は素数') continue break #---- WindowsのVS Codeで赤いブレークポイント(以下 BPn:nは行数)を画像のように置き、変数nとxの挙動をみていたところ、実行直後に n が 2 となり、BP4にに遷移するのは理解できます で、想定していたのは、5行目にxがあるので、 BP5 if n % x == 0: を試してからBP10へ飛ぶと予想してました しかし実際には、BP4→10と遷移しています この挙動で、5行目でストップしなかった理由を教えてください 【回答上のご注意】 回答は、解答(答え)を求めています わたしはプログラマーではないので、昭和的な「自分で考えろ」的なものは求めていません わからなければ答えない自由もあなたにはあります 不明点があれば説明いたします python 3.10.8
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
goto文を用いて説明したのは、モジュールの動作順序を説明する為です。 pythonのgoto、labelモジュールは、正式には実装されておらず、4月1日のエイプリルフールのネタとして公開され、インストールすれば実際に動作しますが、使用しないように警告されています。 goto labelモジュールはpython使用者なら知っているジョークモジュールなので、初心者には相応しくないモジュールです。「そういうのが有るんだ」程度に留めて下さい。 重要なのはgotoやlabelではなく「どこからどういう順番で処理されて、条件ごとに何処に飛ぶか?」です。 その説明に一番適していたのが「goto、labelを用いた説明」だったのです。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
range関数は range(初期値,終了値,増加値) という仕様です。 注意したいのは「終了値は要素に含まれない」という事です。 nが2になっている時に range(2,n) と書くと「2から始まって、n(つまり2)の手前までの要素を生成」します。 つまり「何も生成しない」のです。「空の要素のオブジェクト」を生成します。 for文のイテラブルオブジェクトに「空のオブジェクト」を指定すると、for文は「何もループせず、いきなりelse節を実行」します。 for文を使わず、goto文を使って、for文と同じ事をしてみます。 from goto import goto, label n = 2 label .loop1 if n < 5: x = 2 label .loop2 if x < n: if n % x == 0: print('xは ' + str(x)) print('nは ' + str(n) + ' は割り切れる') goto .end else: x = x + 1 goto .loop2 else: print(n,' は素数') label .end n = n + 1 goto loop1 一番最初でxが2になり、xがnより小さくない(等しい)ので、elseに飛び「2は素数」と表示して、という動作になります。 gotoやifでforと同じ事を書くとゴチャゴチャになりますが、処理の順番が理解できる(いきなりBP10に飛ぶ理由が判る)と思います。
お礼
ありがとうございます コードはIndentationError: unexpected indentエラーが出まくり、修正しても通らないので実行はあきらめましたが、「空の要素のオブジェクトを生成」は覚えておきます
補足
すいません。お時間のあるとき1つ教えてください label .loop1 label .loop2 のような書き方がわたしのチュートリアルに書いてないのでわからないので、AIで調べたのですが、下記のようなLabelクラスの説明しか得られませんでした label = Label(root, text="Hello, world!", bg="white", fg="black", font=("Helvetica", 16), width=20, height=5, padx=10, pady=10) たぶんお使いのlabel .loop1のlabel はモジュール名だと思ったのですが、AIに聞くと 「Pythonには、labelモジュールは存在しません」 と怒られます このlabelは何なのでしょうか? また l .l と.の前にスペースを入れていらっしゃいますが、これは実行上(動作上)必要な書き方なのでしょうか? よろしくお願いいたします。
- f272
- ベストアンサー率46% (8467/18126)
そういうことです。
お礼
ありがとうございます なぜ5行目を試しにいかないのかという疑問が残りましたが、4行目でFalseが返ったため、スキップして10行目に行ったとおぼえておくことにしました 大変たすかりました
- f272
- ベストアンサー率46% (8467/18126)
nが2のとき BP4 for x in range(2, n): ですから、BP5からBP9までのforブロックはnが2から1=n-1までのときにのみ実行し、それ以外のときはelseブロックを実行します。つまりnが2のときには実行しません。
お礼
ありがとうございます お時間あるときでよいのでお伺いさせていただきたいのですが、 実行直後 nは2でスタートし BP4 for x in range(2, 2): となると思います で、わたしの頭の中のrange()の振るまいは 例えば for x in range(2): と書かれていた場合、range(0→1) で実行終了となるとイメージしています (違っていたらご教示ください) この考え方からすると、 BP4 for x in range(2, 2): は range(2→1) となっています すると、 >つまりnが2のときには実行しません。 という意味は、 「range(2→1)は動作が成り立たない:ゆえに実行しない(されない)」 という理解でよろしいでしょうか?
お礼
ありがとうございます labelモジュールはジョークなのですか テスターなのですが、開発部隊のプログラマー(海外)が書いてきたらわからずにいたところなので、知ってよかったです