前回(組み込み関数)と前々回(関数の定義)で、Pythonの関数について見てきました。「ひとまとまりの処理をまとめる」という関数の機能はとても便利ですが、それはプログラミングの機能のひとつの側面にすぎません。今回から、プログラミングの別の側面である「状態に応じて処理を制御する」機能を紹介していきたいと思います。まずは「条件に応じて処理を分岐する」という方法です。
今回の内容
(1) if文
まずは以下の例を見てください(この例から、スペースはスペースとして記述します。自分で書く際には、適宜スペース4個、スペース8個…を補ってください):
>>> def positive_response(x): ... if x > 0: ... print("なんか来た!") ... >>> positive_response(-2) >>> positive_response(0) >>> positive_response(2) なんか来た! >>> positive_response(4) なんか来た! >>> positive_response(-1) >>> ■
最初に定義したpositive_response関数が何をしているかわかるでしょうか?
ここで使われているのがif文と呼ばれる文で、条件が成り立っているときだけif文の本体を実行します。この場合は
- 条件:x>0
- 本体:print(“なんか来た!”)
に当たりますので、関数の引数xが0より大きいときにだけ「なんか来た!」という出力が表示され、それ以外の場合には何も起こらない、という動作になります。
if文の構造は、大まかには関数定義のdef文と同じです。ifと条件式の後にコロンが必要で、これが「この後に文の本体が来ます」ということを示しています。if文の本体はひとつのブロックを構成しますので、ifのところよりもインデントを深くとる必要があります。今回はif文自体が関数の本体の中身になっていますので、if文が始まるところが1ブロック分インデントされ、if文の本体はさらに1ブロック分インデントされて合計2ブロック分になります。関数定義のときと同様、if文本体の内部ではインデントは揃えてください。
(2) 条件式と真偽値
条件式とは?
if文の「条件」として評価できる式のことを、条件式と呼んでいます。条件式には、何を使うことができるのでしょうか?それを知るために、まずはコンソールの環境で「x>0」を評価してみましょう。ただしx>0を評価する前に「x」という名前がないといけないので、適当な値を代入して使います。
>>> x = 2 >>> x > 0 True
新しい値が登場しましたね。せっかくなので、xが0より大きくない場合も見てみましょう:
>>> x = 0 >>> x > 0 False
こんどは別の値が表示されました。True、Falseという値は真偽値あるいは論理値と呼ばれるタイプの値で、プログラミング言語では「ブール代数型(boolean value)」とも呼ばれます。表している内容は単純で、Trueが「1(真、正しい、有)」を、Falseが「0(偽、間違い、無)」を表します。実際コンソールにTrueあるいはFalseと入力すれば、真偽値として解釈されます。trueやfalseのように小文字で始めると認識されないので注意してください!
>>> True True >>> False False >>> true Traceback (most recent call last): File "", line 1, in NameError: name 'true' is not defined >>> type(True) <class 'bool'>
上の最後の例のように、TrueやFalseはboolという型の値です。
真偽値の演算
真偽値には足し算や引き算は使えませんが、その代わり論理演算と呼ばれる演算が定義されています:
>>> True and False False >>> True or False True
ここで各演算の意味は
- x and y:xとyが両方TrueのときのみTrueに評価される
- x or y:xとyのどちらかがTrueであればTrueに評価される
になります。たとえば先ほどの不等号を用いると
>>> x = 2 >>> (x > 0) and (x < 1) False >>> (x > 0) or (x < 1) True
「以上」と「以下」
不等号「>」と「<」は、それぞれ「より大きい」「より小さい」という意味を表します。このため、比較する値そのものはFalseとして評価されてしまいます:
>>> 0 > 0 False
比較する値を含めてTrueにしたい場合、「≥(以上)」や「≤(以下)」に相当する演算記号を使います。もともとこれらの文字は標準の文字セットに入っていなかったので、これらの演算では代わりに「<=」あるいは「>=」という2文字で表現します。
>>> 0 >= 0 True >>> 0 =< 0 True
ちなみに、不等号と等号の順序を逆にするとPythonは認識してくれなくなりますので、注意しましょう:
>>> 0 =< 0 File "", line 1 0=>0 ^ SyntaxError: invalid syntax
この順序は、英語(日本語でもですが)での言い方に由来していると思います。英語で「≥」は”greater equal”、「≤」は”less (smaller) equal”と言うようです。日本語でも「>」は「大なり」、「<」は「小なり」で、「≥」は「大なりイコール」、「≤」は「小なりイコール」と読みますね。「<=」「>=」の順序は、その順序に合わせた記号の書き方になっています。
等号の条件式
今まで不等号を用いた条件式を見てきましたが、当然ながら等号も表現できます。ただ数学で言うところの「a = b」という表記はすでに代入文として使われてしまっていますので、Pythonでは(そして他の多くのプログラミング言語では)別の表記方法「==」で表現します:
>>> x = 1 >>> x == 1 True >>> x == 0 False
上の例のように、「==」のように=をスペース無しで2つ繋げて使うと「等しい」を表現する条件式になります。
代入を表す「=」は、等号を表す「==」と取り違えやすいので注意してください。「if x == 1:」というところで「==」の代わりに「=」を使うとエラーになります:
>>> if x = 1: File "", line 1 if x = 1: ^ SyntaxError: invalid syntax
in演算子
この他、日常では馴染みのないものとして「in」という表現があります。これは「含まれる」を表す演算子です。例えば文字列を用いて、以下のようなことができます:
>>> 'a' in 'abc' True >>> 'd' in 'abc' False >>> "日常" in "日常生活" True >>> "非日常" in "日常生活" False
このように、左辺の式(文字あるいは文字列)が右辺の式(文字あるいは文字列)に「含まれる」かどうか(包含関係)を評価するのがin演算子です。
inを「演算子」と呼んでいますが、これはPythonにおけるinが、+や-と同じように「左辺と右辺の式を評価して演算(処理)する」という記号だからです。ちなみにプログラミング言語によって、inのような包含関係式の実装方法(実現方法)には違いがあります。多くの言語では、このような式は関数として(a in b、という形でなくcontains(b, a)のような形で)実装されていますので注意してください。
(3) 分岐で処理を変える
if-else文
ここまでの例では、条件式が真(True)の場合だけ何かの処理をしてきました。真と偽(False)で別々の処理をしたい、という場合は、if文にelseのブロックを追加したif-else文を使います:
>>> def am_I_nothing(x): ... if x == 0: ... print("Yeah, I'm nothing") ... else: ... print("己の限界に気づいたつもりかい?") ... >>> am_I_nothing(0) Yeah, I'm nothing >>> am_I_nothing(9) 己の限界に気づいたつもりかい?
else(その他、という程度の意味)というキーワードにコロンをつけて、偽の場合の処理を追加しています。真の場合の処理、偽の場合の処理の本体のことを、(しばしばその前のifやelseの行と併せて)「ブロック」と呼ぶことがあります。
ここでのポイントは、以下のとおりです。
- elseの行は、ifと同じ深さのインデントにする
- elseの後にもコロンをつける(その後に処理を書くので)
- elseブロックの本体はifブロックと同様、elseの行よりも1段階インデントを深くする
多岐分岐とelif
もし選択肢が多岐にわたる場合はどうしたらよいでしょうか?たとえば引数xが1の場合、2の場合、3の場合、それ以外の場合で処理を分けたいとします。このとき、if-else文を使って最も素直に処理を記述するとすると、以下のようになるでしょう。
>>> if x == 1: ... (処理1) ... else: ... if x == 2: ... (処理2) ... else: ... if x == 3: ... (処理3) ... else: ... (処理それ以外)
新しい条件は以前の条件のelseブロックの中で評価することになるので、どんどんインデントが深くなっていき、「xの値に応じて複数に分岐する」という概念とあまり一致したコードになりません。
そこでこれを回避するために、Pythonではelif(else ifの省略形)という表現があります:
>>> if x == 1: ... (処理1) ... elif x == 2: ... (処理2) ... elif x == 3: ... (処理3) ... else: ... (処理それ以外)
上の書き方のように、else + if文の部分をelifのブロックで記述することで、処理の見た目をフラットなまま保つことができます(これはC言語やJavaで言うところのswitchにあたる処理になります)。
elifを使う場合でも、最後にelseブロックを持ってくることができます。この場合elseブロックの処理が実行されるのは、以前のif/elifの条件式全てが偽であった場合だけです。またelseの性質上、elseブロックの後にelifブロックを書くとエラーになるので注意してください。
(4) 次のステップ
今回は条件式とは何かというところから、条件式の値によって処理を分岐する方法を紹介しました。次回はループを処理する方法を紹介してみたいと思います。
“Pythonの文と式(5): if文を用いた条件分岐” への 2 件のフィードバック