If文

異なる状況や条件に対して対応を選択することが可能になるため,if文を使うとプログラムに全く新しい可能性が開かれます。この節では特定の条件に対してどのようにテストし,条件に対応して適切に対応する方法について学びます。

if文とは

if文は条件をテストし,その条件に対応します。もし(if)条件が真なら次に並んでいる動作が実行されます。複数の条件を一度にテストして,それぞれの条件に適切に対応することもできます。

次に示すのは,私が好きなデザートを示す例です。デザートを列挙し,一番好きなものをお教えしています。

# A list of desserts I like.
desserts = ['ice cream', 'chocolate', 'apple crisp', 'cookies']
favorite_dessert = 'apple crisp'

# Print the desserts out, but let everyone know my favorite dessert.
for dessert in desserts:
    if dessert == favorite_dessert:
        # This dessert is my favorite, let's let everyone know!
        print("%s is my favorite dessert!" % dessert.title())
    else:
        # I like these desserts, but they are not my favorite.
        print("I like %s." % dessert)
I like ice cream.
I like chocolate.
Apple Crisp is my favorite dessert!
I like cookies.

このプログラムで何が起こっているか

  • このプログラムはデザートのリストで始まり,そのうちの一つがお気に入りとしています。
  • forループは全てのデザートをたどっています。
  • forループの内側では,リストの各要素を調べます。
    • もし現在のdessertの値がfavorite_dessertと等しいときは,それがお気に入り(is my favorite)であるというメッセージを表示します。
    • もし現在のdessertの値がfavorite_dessertと等しくないときは,そのデザートが好き(I like)であるというメッセージを示します。

if文では複数のテストを必要なだけ使うことができます。その例は後で少し示します。

論理テスト

if文は全てTrue(真)またはFalse(偽)に評価されます。TrueFalseはPythonのキーワードです。キーワードとは,特別な意味が付いているものを指します。if文では,次に示す条件をテストできます。

空白文字

PEP 8について学んだことを覚えていますか。PEP 8の一節和訳)には,比較演算子の両側にスペースを一つずつ入れる方が良いとあります。どういうことか分からない場合は,以下の例に従ってみましょう。

等値

二つの要素が等値であるのは,それらが同じ値を持つときです。等値性は,数値や文字列,後で習うその他のオブジェクトの間に対してテストできます。結果に驚くこともあるので,以下の例を注意深く見ていくことにしましょう。

Pythonは,他の多くのプログラミング言語同様,二つの等号で等値性をテストします。

注意! 誤って一つの等号を使うと,テストができずに要素にテストしようとしている値を格納してしまいます。

5 == 5
Out[3]:
True
3 == 5 
Out[4]:
False
5 == 5.0
Out[24]:
True
'eric' == 'eric'
Out[8]:
True
'Eric' == 'eric'
Out[9]:
False
'Eric'.lower() == 'eric'.lower()
Out[10]:
True
'5' == 5
Out[11]:
False
'5' == str(5)
Out[12]:
True

非等値

二つの要素が等しくないのは,それらが同じ値を持たないときです。Pythonでは非等値は感嘆符と等号一つでテストします。

等値をテストしてそれが成り立たないときに非等値とすることがあります。むしろ非等値を直接テストした方が理にかなうこともあります。

3 != 5
Out[13]:
True
5 != 5
Out[14]:
False
'Eric' != 'eric'
Out[18]:
True

top

その他の関係

より大きい

5 > 3
Out[16]:
True

以上

5 >= 3
Out[19]:
True
3 >= 3
Out[20]:
True

未満

3 < 5
Out[21]:
True

以下

3 <= 5
Out[22]:
True
3 <= 3
Out[23]:
True

top

リスト中の要素の存在

要素がリスト中にあるかをinキーワードを使って調べることができます。

vowels = ['a', 'e', 'i', 'o', 'u']
'a' in vowels
Out[25]:
True
vowels = ['a', 'e', 'i', 'o', 'u']
'b' in vowels
Out[26]:
False

練習問題

TrueとFalse

  • 10行以上のプログラムを書いてください。ブログラムの行それぞれに論理文を含めてください。プログラムは5つのTrueと5つのFalseを出力するものとします。
  • 注: 単に5 > 3ではなくprint(5 > 3)と書く必要があると思います。

if-elif...else構造

必要に応じて一連の条件をテストしたり,条件の組合せをテストしたりすることができます。

<a id="Simple-if-statements></a>

単純if文

最も簡単なテストはif文だけからなるもので,条件がTrueのときに一つの文を実行するものです。

dogs = ['willie', 'hootz', 'peso', 'juno']

if len(dogs) > 3:
    print("Wow, we have a lot of dogs here!")
Wow, we have a lot of dogs here!

この例では条件が成り立たないときは何も起こりません。

dogs = ['willie', 'hootz']
if len(dogs) > 3: print("Wow, we have a lot of dogs here!")

エラーは発生しないことに注意しましょう。条件len(dogs) > 3はFalseに評価され,プログラムはifブロックの後の行に移ります。

if-else文

多くの場合,テストが取りうる真偽に対してそれぞれ対応する必要があります。テストがTrueに評価されるときあることをして,Falseの時は別のことをします。if-else構造を使うと,次の例のように簡単に実現できます。

dogs = ['willie', 'hootz', 'peso', 'juno']

if len(dogs) > 3:
    print("Wow, we have a lot of dogs here!")
else:
    print("Okay, this is a reasonable number of dogs.")
Wow, we have a lot of dogs here!

結果は変わらないのは,テストがTrueに評価されてif文の下の文だけが実行されているからです。elseの下の文は,テストが不成立の時にのみ実行されます。

dogs = ['willie', 'hootz']
if len(dogs) > 3: print("Wow, we have a lot of dogs here!") else: print("Okay, this is a reasonable number of dogs.")
Okay, this is a reasonable number of dogs.

テストはFalseと評価されましたので,elseの下の文が実行されました。

if-elif...else分岐

単にどちらかというだけでなく,一連の条件をテストしたいことも多くあります。これは,if-elif-else文を使えばできます。

テストできる条件の数に制約はありません。常に一つif文から分岐を始めて,elseも一つだけです。しかしelifは必要なだけいくつでも使えます。

dogs = ['willie', 'hootz', 'peso', 'monty', 'juno', 'turkey']

if len(dogs) >= 5:
    print("Holy mackerel, we might as well start a dog hostel!")
elif len(dogs) >= 3:
    print("Wow, we have a lot of dogs here!")
else:
    print("Okay, this is a reasonable number of dogs.")
Holy mackerel, we might as well start a dog hostel!

重要な点は,この例で最初のifだけが評価されていることです。if-elif-else分岐では,テストが一度成立すれば残りの条件は無視されます。

dogs = ['willie', 'hootz', 'peso', 'monty']
if len(dogs) >= 5: print("Holy mackerel, we might as well start a dog hostel!") elif len(dogs) >= 3: print("Wow, we have a lot of dogs here!") else: print("Okay, this is a reasonable number of dogs.")
Wow, we have a lot of dogs here!

最初のテストが不成立なので,Pythonは2番目のテストを評価しました。このテストが成立したのでlen(dogs) >= 3に対応する文が実行されます。

dogs = ['willie', 'hootz']
if len(dogs) >= 5: print("Holy mackerel, we might as well start a dog hostel!") elif len(dogs) >= 3: print("Wow, we have a lot of dogs here!") else: print("Okay, this is a reasonable number of dogs.")
Okay, this is a reasonable number of dogs.

この例では,最初の二つのテストが不成立なので,else節の文が実行されます。この文は犬が全くいなくても成り立つことに注意してください。

dogs = []
if len(dogs) >= 5: print("Holy mackerel, we might as well start a dog hostel!") elif len(dogs) >= 3: print("Wow, we have a lot of dogs here!") else: print("Okay, this is a reasonable number of dogs.")
Okay, this is a reasonable number of dogs.

一連のif文を始めるときには何もする必要はありません。犬がいないときに何もしないようにするには,else節をもう一つのelif節に置き換えれば良いでしょう。

dogs = []

if len(dogs) >= 5:
    print("Holy mackerel, we might as well start a dog hostel!")
elif len(dogs) >= 3:
    print("Wow, we have a lot of dogs here!")
elif len(dogs) >= 1:
print("Okay, this is a reasonable number of dogs.")

この例では,最低1頭の犬がいる場合にだけメッセージを表示しています。もちろん,else節をさらに追加して犬が全くいない場合に対応することもできます。

dogs = []

if len(dogs) >= 5:
    print("Holy mackerel, we might as well start a dog hostel!")
elif len(dogs) >= 3:
    print("Wow, we have a lot of dogs here!")
elif len(dogs) >= 1:
    print("Okay, this is a reasonable number of dogs.")
else:
print("I wish we had a dog here.")
I wish we had a dog here.

以上に見られるように,if-elif-else分岐を使うと与えられた場合に対して特定の対応ができます。

練習問題

3人では群衆

  • リストを作り,最低4名の名前を含めてください。
  • ifテストを使って,リストに3人以上いるときは満員であることを示すメッセージを印字してください。
  • リストを修正して二人だけにしてください。人々をリストから取り除くメソッドを使い,単にリストを再定義しないようにします。
  • ifテストを再び走らせます。今度はリストに3人未満しかいないので出力はないはずです。
  • ボーナス: ifテストcrowd_testのような関数に入れましょう。 (訳注: Two is company, three is a crowd. 二人は友人,三人は他人。ことわざ)

3人では群衆 - その2

  • 3人では群衆のプログラムを新しい名前で保存してください。
  • else文をifテストに追加してください。else文が実行されたら,空席ありというメッセージを印字してください。

6人だと暴徒

  • 3人では群衆 - その2のプログラムを新しい名前で保存してください。
  • リストに名前を付け加えて,6人以上にしてください。
  • テストを次のように修正しましょう。
    • 5人より多いときは,超満員というメッセージを出力します。
    • 3〜5人のときは満員というメッセージを出力します。
    • 一人か二人のときは,空席ありというメッセージを出力します。
    • 部屋に人がいないときは,部屋は空室というメッセージを出力します。

これまで見てきた例は,一つのテストを通っただけでした。最初のテストが成立すると残りは無視されます。このふるまいは,コードが効率よく走るには良いことです。多くの場合,一つの条件に当てはまればよく,その後の全ての条件は無意味だからです。

他方,一連のテストを走らせて,全てのテストを通したいこともあります。テストのいくつか又は全てを行なって,それぞれのテストに対して対応が必要になることがあります。次の例では,居合せた全ての犬に挨拶します。

dogs = ['willie', 'hootz']

if 'willie' in dogs:
    print("Hello, Willie!")
if 'hootz' in dogs:
    print("Hello, Hootz!")
if 'peso' in dogs:
    print("Hello, Peso!")
if 'monty' in dogs:
    print("Hello, Monty!")
Hello, Willie!
Hello, Hootz!

if-elif-else分岐を使ったら,最初の犬だけに挨拶するところでした。

dogs = ['willie', 'hootz']

if 'willie' in dogs:
    print("Hello, Willie!")
elif 'hootz' in dogs:
print("Hello, Hootz!")
elif 'peso' in dogs:
print("Hello, Peso!")
elif 'monty' in dogs:
print("Hello, Monty!")
Hello, Willie!

もちろん,もっときれいに書くには,リストとforループを使います。次の例は分かりますよね。

dogs_we_know = ['willie', 'hootz', 'peso', 'monty', 'juno', 'turkey']
dogs_present = ['willie', 'hootz']

# Go through all the dogs that are present, and greet the dogs we know.
for dog in dogs_present:
    if dog in dogs_we_know:
        print("Hello, %s!" % dog.title())
Hello, Willie!
Hello, Hootz!

このようなコードを書くことを目指してください。最初は効率の悪いコードでも構いません。一つのプログラム中に同じようなコードを繰り返し書いていることに気づいたら,ループや関数を使って余計なコードを減らせないか検討してみましょう。

真偽値

全ての値は真または偽に評価することができます。一般的なルールは0ではないか空でない値はTrueです。もしどちらになるか自信がないときは,Pythonのターミナルを開いて2行書いてみて考えている値がTrueFalseか調べてみましょう。次の例を見て,それを心に留めておいて,興味を持った値をテストしてみましょう。私は通常長いテストを使って毎回何かが印字されるようにしています。

if 0:
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to False.
if 1:
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to True.
# Arbitrary non-zero numbers evaluate to True.
if 1253756:
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to True.
# Negative numbers are not zero, so they evaluate to True.
if -1:
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to True.
# An empty string evaluates to False.
if '':
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to False.
# Any other string, including a space, evaluates to True.
if ' ':
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to True.
# Any other string, including a space, evaluates to True.
if 'hello':
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to True.
# None is a special object in Python. It evaluates to False.
if None:
print("This evaluates to True.") else: print("This evaluates to False.")
This evaluates to False.

総合発展問題

宇宙人ゲーム

  • リストを作り,10の宇宙人を格納してください。宇宙人の色は次の'red', 'green', 'blue'のうち一つであるとします。
    • 短く'r', 'g','b'としても構いませんが,その場合はr, g, bが何を指すかコメントを書いておきましょう。
  • 赤い宇宙人は5点,緑の宇宙人は10点,青の宇宙人は20点とします。
  • ループを使ってプレーヤーが全ての宇宙人を退治したら何点取りうるか計算してください。
  • ヒント

ヒント

ヒントは一番下にあるので,ヒントを見ないで練習問題を解くこともできるようにしてあります。

宇宙人インベーダー

  • 宇宙人のリストを定義した後,current_scoreまたはcurrent_pointsという名前の変数に0を入れてください。
  • ループの中に現在の得点に何点加えるか決める一連のテストを書いてください。
  • 総合得点を勘定するために,current_score = current_score + pointsという構文を使ってください。ここでpointsは現在の宇宙人に対する得点です。