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

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

ただいまの
回答率

87.33%

ifとreturnのインデントの位置について

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,599

score 16

前提・実現したいこと

インデントの使い方で困っています、ご回答いただけますと幸いです

具体的には{該当のソースコード}の5行目#( ↓ここのreturnの位置のことですの行)のreturn Trueのインデントの位置です
3行上のifに揃えないと実行できないのですが、なぜでしょうか?

if文が終わっている、if文を抜け出しているはずなのでreturn Trueの位置はどこでもよいと思うのですが納得できません。

もし
else return True 
と書くならば、ifとelse return True のインデントは揃えないといけないのは理解しております

昔C言語を学校で学んでいた際、C言語はインデントは揃えていた記憶がありません(これは私の勘違いかもしれませんが)
ご回答いただけますと幸いです、よろしくお願いします

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

def   validate(hand):
 if hand < 0 or hand > 2:
        return False
    # ↓ここのreturnの位置のことです
 return True

def print_hand(hand, name='ゲスト'):
    hands = ['グー', 'チョキ', 'パー']
    print(name + 'は' + hands[hand] + 'を出しました')

print('じゃんけんをはじめます')
player_name = input('名前を入力してください:')
print('何を出しますか?(0: グー, 1: チョキ, 2: パー)')
player_hand = int(input('数字で入力してください:'))

if validate(player_hand):
    if player_name == '':
        print_hand(player_hand)
    else:
        print_hand(player_hand, player_name)
else:
    print('正しい数値を入力してください')

試したこと

return Trueの位置をいろいろ変えて実行しました
結果は上記にも記載の通り二行上のifに揃えたときのみ実行できました

補足情報(FW/ツールのバージョンなど)

コードはprogateと言うプログラミング学習サイトの[pythonコース]の[python3(レッスン3)]の[returnの性質]から引用しています

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+5

if文が終わっている、if文を抜け出しているはずなのでreturn Trueの位置はどこでもよいと思うのですが納得できません。

ifブロックと同じ階層にあることが重要なのです。
次のように書いてエラーになるのと同じです。

print('hello')
 print('world')

昔C言語を学校で学んでいた際、C言語はインデントは揃えていた記憶がありません(これは私の勘違いかもしれませんが)

構文の特徴の違いです。
C系の言語は過剰な空白文字を無視しますが、Pythonの場合インデントが深い意味を持ちます。

前者はフリーフォーマット、後者はオフサイドルールなんて呼ばれてますね。
Pythonがオフサイドルールを採用している理由については、このように述べられています。

Python はなぜ文のグループ化にインデントを使うのですか?

...中略...
時折、C のプログラマはこのようなコード片に出くわします:

if (x <= y)
        x++;
        y--;
z++;


この条件文が真の時のみ実行されるのは x++ 文だけですが、このインデントでは誤解を招きます。経験を積んだ C プログラマでさえ、 y が x > y の時にもデクリメントされるのはなぜか分からず長いこと立ち止まることがあるでしょう。

引用元: Python よくある質問 » デザインと歴史 FAQ

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/17 21:15

    修正後も回答してくださりありがとうございます!
    print('hello')
    print('world')
    の例はとても参考になりました。

    簡潔かつ早く、私が知りたいことを教えてくださいました!
    ありがとうございました

    キャンセル

+2

たぶん3パターンかなと思うので、列挙します。

質問文にある通りのインデント

def validate(hand):
    if hand < 0 or hand > 2:
        return False

    return True
  1. (関数が呼び出されたとして)関数が呼び出されます。
  2. 関数の処理としてif文に入ります。
    2-1. handが0未満もしくは2より大きければFalseが返ります。(このあとの処理はされない)
  3. 関数の処理の続きでTrueが返ります。

質問文にあるインデントからもう1個足したもの(return Falseと同じ)

def validate(hand):
    if hand < 0 or hand > 2:
        return False

        return True
  1. (関数が呼び出されたとして)関数が呼び出されます。
  2. 関数の処理としてif文に入ります。
    2-1. handが0未満もしくは2より大きければFalseが返ります。(このあとの処理はされない)
    (2-2.) 処理が続かないのでreturn Trueは実行されません。

この場合、handが0以上2以下ならNoneが返ります(たぶん)

質問文にあるインデントから1個抜いたもの(def validate(hand):)と同じ

def validate(hand):
    if hand < 0 or hand > 2:
        return False

return True


 エラーとなります。 

  1. (関数呼び出しが行われず)return Trueになりますが、関数外なのでエラーです。

※関数呼び出しの前にエラーになっているので関数呼び出し後の処理は省略

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/17 21:16

    ご回答ありがとうございます!
    とても参考になりました!

    キャンセル

+1

そのreturn Truedef以下のブロックに属します。なので、上のifと同じレベルに揃える必要があります(言語仕様上はスペース・タブ幾つであっても構いませんが、同一のブロック階層のものはすべて等しいレベルにないと動作しません。現実的には乱れると大変なので、スペース4つ単位をおすすめします)。

ちょっとむずかしいですが、言語リファレンスに説明が書いてあります。

2. 字句解析 — Python 3.6.5 ドキュメント | 2.1.8. インデント

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/17 21:16

    ご回答ありがとうございます!
    とても参考になりました!

    キャンセル

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

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

関連した質問

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