• 締切済み

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

この投稿のマルチメディアは削除されているためご覧いただけません。
  • ketae
  • お礼率86% (295/343)
  • Python
  • 回答数4
  • ありがとう数4

みんなの回答

  • chie65535
  • ベストアンサー率43% (8524/19375)
回答No.4

goto文を用いて説明したのは、モジュールの動作順序を説明する為です。 pythonのgoto、labelモジュールは、正式には実装されておらず、4月1日のエイプリルフールのネタとして公開され、インストールすれば実際に動作しますが、使用しないように警告されています。 goto labelモジュールはpython使用者なら知っているジョークモジュールなので、初心者には相応しくないモジュールです。「そういうのが有るんだ」程度に留めて下さい。 重要なのはgotoやlabelではなく「どこからどういう順番で処理されて、条件ごとに何処に飛ぶか?」です。 その説明に一番適していたのが「goto、labelを用いた説明」だったのです。

ketae
質問者

お礼

ありがとうございます labelモジュールはジョークなのですか テスターなのですが、開発部隊のプログラマー(海外)が書いてきたらわからずにいたところなので、知ってよかったです

  • chie65535
  • ベストアンサー率43% (8524/19375)
回答No.3

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に飛ぶ理由が判る)と思います。

ketae
質問者

お礼

ありがとうございます コードはIndentationError: unexpected indentエラーが出まくり、修正しても通らないので実行はあきらめましたが、「空の要素のオブジェクトを生成」は覚えておきます

ketae
質問者

補足

すいません。お時間のあるとき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% (8019/17138)
回答No.2

そういうことです。

ketae
質問者

お礼

ありがとうございます なぜ5行目を試しにいかないのかという疑問が残りましたが、4行目でFalseが返ったため、スキップして10行目に行ったとおぼえておくことにしました 大変たすかりました

  • f272
  • ベストアンサー率46% (8019/17138)
回答No.1

nが2のとき BP4 for x in range(2, n): ですから、BP5からBP9までのforブロックはnが2から1=n-1までのときにのみ実行し、それ以外のときはelseブロックを実行します。つまりnが2のときには実行しません。

ketae
質問者

お礼

ありがとうございます お時間あるときでよいのでお伺いさせていただきたいのですが、 実行直後 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)は動作が成り立たない:ゆえに実行しない(されない)」 という理解でよろしいでしょうか?

関連するQ&A

  • VBAでifとかelseとかelseifとかの後に書く文

    VBAでifとかelseとかelseifとかの後に書く文の出力で 現在プログラムを書きました。2行書く場合 たとえば else if 『a』を出力させるプログラム 『b』を出力させるプログラム Sheets("Sheet2").Range("A1").Value = Application.WorksheetFunction.Clean(StrConv(toDateStr(a(0)), vbWide)) Sheets("Sheet2").Range("A2").Value = Application.WorksheetFunction.Clean(StrConv(toDateStr(a(1)), vbWide)) をプログラム書いた場合、実行されるのは『a』を出力させるプログラムだけなのですが、else ifの後は次の1行目しかこのプログラムだと実行できない感じなのでelse ifの中に2行文の内容をいれたいのですが else if()で全部囲めばいいのか? else if{}で全部囲んだりするのか?このような全部ひっくるめられるプログラムはないのでしょうか? お願いします。教えてください

  • vbsのfor文に対する質問です。

    vbsのfor文に対する質問です。 Javaでいうところのbreak文と同様の処理はどのようにすれば良いのでしょうか? 例) For i=1 to 10 step 1   If str = "" Then    // for文を抜ける処理   End If next

  • Excel VBA の if elseについて

     以下は与えられた自然数が素数であるかどうかを判定する、Excel VBA による素朴なコードです。  自然数が2 とそれ以上の場合で処理を分けていますが、5 行目のelseで   対応するifがないという というコンパイルエラーが出ます。私はプログラミング言語は、Pascal しか経験がなく、Pascal の場合 5 行目の else から後の処理したい複数の構文を begin end で囲めば問題なく動きます。  Excel VBA で同じ処理をさせるにはどうしたらいいのでしょうか?  Worksheets("素数").Activate  '"素数"シートをアクティブにする  Flg = 0  Target = Range("D5").Value  if Target = 2 then MsgBox ("2 は素数です。")  else  'else 対応するifがないというエラーが出る  'begin ・・・・・ Pascalの場合    K = Int(Target / 2)    ' 2 以外の素数は奇数なので偶数で割ることを確認する必要はない。    For I = 3 To K Step 2     If Target Mod I = 0 Then      Flg = 1      Exit For     End If    Next I       Snum = Format(Target)    If Flg = 0 Then     MsgBox (Snum + " は素数です。")    Else     MsgBox (Snum + " は素数ではありません。")    End If  'end ・・・・・ Pascalの場合  End If

  • 2010 excel マクロ 記号の変化

    エラー発生で強制終了になってしまいます。2007年のexcelで作成したものですが、2010だと強制終了になってしまいます。 内容は□をダブルクリックすると■になるように作っています。 記述は2003年からのマクロ記述なので、変化が必要なのでしょうか? Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) 'Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'セルをダブルクリックすると、・→○→△→×→・と変更する。 Dim S1 As String Dim S2 As String Dim S01 As String Dim S02 As String Dim S03 As String Dim S04 As String S1 = "□" S2 = "■" S01 = "・" S02 = "○" S03 = "△" S04 = "×" On Error GoTo ERR_12 sCheckXY S1, S2 sCheckX1234 S01, S02, S03, S04 sChangeXY S1, S2 Exit Sub ERR_12: End End Sub Sub sChangeXY(X As String, Y As String) '選択セルに□があれば■に変える Dim Str0 As String 'str1の左端 Dim Str1 As String 'strの右側更新 Dim Str2 As String 'strの左側更新 Dim Str20 As String 'strの左側一部保存 Dim L As Long Dim M As Long Dim N As Long Str1 = ActiveCell.Text L = Len(Str1) Debug.Print L If L = 0 Then End End If For N = 1 To L Debug.Print Str2 Str0 = Left(Str1, 1) If Str0 = X Or N = L Then If Str20 <> "" Then If N = L Then Str20 = Str20 + Str0 End If If MsgBox(Str20 & "  はチェックしますか?", vbYesNo, "選択肢") = vbYes Then Str2 = Str2 + Replace(Str20, X, Y) Str20 = Str0 Else Str2 = Str2 + Replace(Str20, Y, X) Str20 = Str0 End If Else Str20 = Str0 End If Else Str20 = Str20 + Str0 End If Str1 = Right(Str1, L - N) Next N ActiveCell.Value = Str2 End Sub Sub sCheckXY(X As String, Y As String) '選択セルがXならY,YならXにチェックをかえる If ActiveCell.Text = X Then ActiveCell.Value = Y End ElseIf ActiveCell.Text = Y Then ActiveCell.Value = X End End If End Sub Sub sCheckX1234(X1 As String, X2 As String, X3 As String, X4 As String) '選択セルがXならY,YならXにチェックをかえる If ActiveCell.Text = X1 Then ActiveCell.Value = X2 End ElseIf ActiveCell.Text = X2 Then ActiveCell.Value = X3 End ElseIf ActiveCell.Text = X3 Then ActiveCell.Value = X4 End ElseIf ActiveCell.Text = X4 Then ActiveCell.Value = X1 End End If End Sub

  • pythonについて

    pythonについて質問があります。 下記の組み合わせプログラムで、comb'(n,m)のn.mをループさせて、m=1から5、n=1から5のようにループさせたいと思っています。 どなたかご教授ください。 def comb(n, m, a = []): if m == 0: print a elif n == m: print range(1, m + 1) + a else: comb(n - 1, m, a) comb(n - 1, m - 1, [n] + a) よろしくお願いします。

  • python3

    def walk(): for i in range(hor): if i == hor_now: print("*", end="") for h in range(var - 1): print("〇",end ="") print() else: for h in range(var): print("〇",end ="") print() print(walk) 普通に出力することはできるんですが、defでユーザー定義関数にすると<function walk at 0x000001541505B9D0>こうなってしまいます、なぜでしょうか?

  • 簡単な配列の作り方

    やりたいことがあるのですが、原始的なやり方しか思いつきません。 簡単な方法があればご教授願いたく思い質問いたしました。 よろしくお願いします! <やりたいこと> 明細行が5件ありまして、それぞれの行に有効かどうかフラグがある。 5件のうち有効になっている数だけの配列を作成する。 --------------------------------------------- 例1)1,2,3,4,5のうち2,3,5の3行が有効の場合   String[] str = String[]{2,3,5} 例2)1,2,3,4,5のうち4の1行が有効の場合   String[] str = String[]{4} --------------------------------------------- <現在やっていること> // 有効行の判断用 private boolean yukoFlg1 = false; private boolean yukoFlg2 = false; private boolean yukoFlg3 = false; private boolean yukoFlg4 = false; private boolean yukoFlg5 = false; // 有効行の数 private long yukoCnt = 0; /** * 該当行分の配列にする String[] * @param str 配列にしたい値 */ public String[] setStrArray ( String str1, String str2, String str3, String str4, String str5) throws Exception { String[] result = null; // 有効行の数が1の場合 if (yukoCnt == 1) { if (yukoFlg1) { result = new String[]{str1}; } else if (yukoFlg2) { result = new String[]{str2}; } else if (yukoFlg3) { result = new String[]{str3}; } else if (yukoFlg4) { result = new String[]{str4}; } else { result = new String[]{str5}; } // 有効行の数が2の場合 } else if (yukoCnt == 2) { if (yukoFlg1) { if (yukoFlg2) { result = new String[]{str1, str2}; } else if (yukoFlg3) { result = new String[]{str1, str3}; } else if (yukoFlg4) { result = new String[]{str1, str4}; } else { result = new String[]{str1, str5}; } } else if(yukoFlg2) { if (yukoFlg3) { result = new String[]{str2, str3}; } else if (yukoFlg4) { result = new String[]{str2, str4}; } else { result = new String[]{str2, str5}; } } else if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str3, str4}; } else { result = new String[]{str3, str5}; } } else { result = new String[]{str4, str5}; } // 有効行の数が3の場合 } else if (yukoCnt == 3){ if (yukoFlg1) { if (yukoFlg2) { if (yukoFlg3) { result = new String[]{str1, str2, str3}; } else if (yukoFlg4) { result = new String[]{str1, str2, str4}; } else { result = new String[]{str1, str2, str5}; } } else if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str1, str3, str4}; } else { result = new String[]{str1, str3, str5}; } } else { result = new String[]{str1, str4, str5}; } } else if (yukoFlg2) { if (yukoFlg3) { if (yukoFlg4) { result = new String[]{str2, str3, str4}; } else { result = new String[]{str2, str3, str5}; } } } else { result = new String[]{str3, str4, str5}; } // 有効行の数が4の場合 } else if (yukoCnt == 4) { if (!yukoFlg1) { result = new String[]{str2, str3, str4, str5}; } else if (!yukoFlg2) { result = new String[]{str1, str3, str4, str5}; } else if (!yukoFlg3) { result = new String[]{str1, str2, str4, str5}; } else if (!yukoFlg4) { result = new String[]{str1, str2, str3, str5}; } else { result = new String[]{str1, str2, str3, str4}; } // 有効行の数が5の場合 } else { result = new String[]{str1, str2, str3, str4, str5}; } return result; }

    • ベストアンサー
    • Java
  • 10*10行の表をforループで作りたい

    表を数字1から100まで10行*10行作りたいと思っています。1~10までい ったら次の行、11~20までいったら次の行というように作成したいとおもっ ています。 for($x=1;$x<=10;$x++){ print "<TR>"; for($i=1;$i<=10;$i++){ print "<TD>$i</TD>"; } print "</TR>"; と書くと10行*10行の表は作れるのですが、1~10までのものが10行できてし まいます。これを1~100までの数字を10行*10行にどのようにすればよいで しょうか?

    • ベストアンサー
    • PHP
  • 指定したセルに1がない時、For を抜けたいのですが・・・

    Office XP Personal 2002 Excel 2002 指定した範囲セルに1がない時、下記の1つの For だけ を抜けたいのですが・・・ どのように変更すればよろしいでしょうか? よろしくお願い致します。 Sub test() Dim i As Integer Dim n As Range For i = 1 To Worksheets.Count - 1  Worksheets(i).Activate  For Each n In .Range("E6", .Range("E6").End(xlDown))   If Not n.Cells.Value = 1 Then   End If   Next n    MsgBox "「1」 がありません。", 48   Exit For  'For Each n In .Range("E6", .Range("E6").End(xlDown))   '続く   '・    '・ End Sub

  • python: ストアする値を更新するコード

    pythonコードの質問です 入力は、画像のExcelシートのA列のようになっています 1行目:その後入力される単語の数 2行明以降:テキスト(ここでは野菜名) これに対して次のコードで「判定」をかけました #----------------------- #数値入力(入力される単語数) t = int(input()) flag = 0 store = 0 i = 0 for i in range(t): #野菜名判定 txt = input() #Tomatoの入力を1として変数flagに代入 if txt.count("Tomato") == 1: flag = 1 store = flag print("iは " + str(i) + "-----") print("判定 " + str(flag == 1 & (store - i) > 0)) print("storeは " + str(store)) i += 1 else: flag = 0 print("iは " + str(i) + "-----") print("判定 " + str(flag == 1 & (store - i) > 0)) print("storeは " + str(store)) i += 1 #----------------------- 2番め以降の入力を for i in range(t)で回し、"Tomato"がみつかると、flagに1を立てます そしてflagの値を、次に"Tomato"が出現するまでstoreに代入して保存 flag == 1 (Tomatoが出現した入力)and (store - i) > 0 となった場合にTrue それ以外はFalse 判定をさせようとしています "Tomato"が入力されても、一定期間はTrue判断にしたくないため、 (store - i) > 0 でジャッジしています ところがi == 7のとき、storeの値が本来storeで8になるべきところが、1のまま変化がおきていないため、本来"判定"がTrueであるべきがFalseとなります store値を上の条件「(store - i) > 0」で更新させたい つまり i が 7のとき、store は 8 ですが、コードのどこが間違っているのでしょうか 他のジャッジ方法でもかまいません

専門家に質問してみよう