PyQオフィシャルブログ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonのandとorはif文以外でも使える?andとorの動作が面白いという話をします

f:id:nana_yu:20181009164316p:plain id:hirokiky です。 PyQ のスタンダードプランでいくつか面白い質問をいただいたので、ブログでも紹介します。

今回は「Pythonのandとorはif文以外でも使える?」という話と、「andとかorは実は思った以上に面白い動作をしている」という話をします。

知っていると混乱が減ったり、便利に使える場合があったりします。 何よりプログラミング言語の美しさを感じられるのでぜひ読んでみてください。

ターゲットになる人

内容としてはPythonを始めたばかり 〜 慣れてきた中級くらいの人を対象に書いています。

いきなり深い話をして分かりにくくならないようにするために、曖昧な表現になっている部分があります。 詳しい人にとっては曖昧な表現に読めるところもあるかもしれませんが、ご了承ください。

間違えている場所があれば教えてください。

andとorの動作を解説します

Pythonの if文などで使う andor 、このブール演算子の動作について解説します。 まず、Pythonの or は、「または」という条件で使う演算子でしたね。

A B A or B
False False False
False True True
True False True
True True True

「片側だけでも『真』なら『真』」と覚えられます。

以下の例では True or False => True とすることで、必ず実行されるif文の処理を書いています。

a = True
b = False

if a or b:
    print("a or b was True")  # このprint関数は実行される

orの正体は

ですが実は、 or 演算子は単に「または」を扱う演算子でなく、以下のような動作をする演算子です。

  • or の左が「真」の場合、左の値を返す
  • or の左が「偽」の場合、右の値を返す

例えば True or False の場合「 or の左が「真」なので、左の値 True を返す」という動作になります (True は真として、 False は偽として判定されます)。 仕様として理解しているような「左が True で右が False だから True を返す」という動作ではありません。

少しややこしいですが、それぞれ以下のようになります。

  • True or True: 結果はTrue。orの左が「真」だから、左の値Trueを返すと動作しています
  • True or False: 結果はTrue。orの左が「真」だから、左の値Trueを返す
  • False or True: 結果はTrue。orの左が「偽」だから、右の値Trueを返す
  • False or False: 結果はFalse。orの左が「偽」だから、右の値Falseを返す

このように動作することで、 or はブール演算としての「または」という機能が果たされています。

Python公式ドキュメントでは以下に書かれています。

https://docs.python.org/ja/3/library/stdtypes.html#boolean-operations-and-or-not

「真」とか「偽」って何?という方はこちらも参考にしてください

docs.pyq.jp

andはどうなる?

andTrue and True の場合 True で、それ以外は False というブール演算子ですね。

A B A or B
False False False
False True False
True False False
True True True

この and は以下のような動作になります。

  • and の左が「真」の場合、右の値を返す
  • and の左が「偽」の場合、左の値を返す

これも分解して考えていくと、この動作でブール演算としての and の機能を果たしてくれます。

ブール値以外でもand、orは使える

ここで値の「真」、「偽」は True や False でなく、文字列などでも判定できます。 Pythonでは文字列の場合、1文字以上の文字列であれば「真」、0文字であれば「偽」と扱われます。

  • "Hello" or "Goodbye": "Hello"(orの左が「真」だから、左の値を返す)
  • "Hello" or "": "Hello"(orの左が「真」だから、左の値を返す)
  • "" or "Goodbye": "Goodbye"(orの左が「偽」だから、右の値を返す)
  • "" or "": ""(orの左が「偽」だから、右の値を返す)

if文の中でなくてもand、orは使える

andor のブール演算子はif文内でよく使いますが、それ以外の場所でも使えます。 例えば以下の処理では、関数の引数 l がない場合は空リストを設定するという処理をしています。

def print_list(l=None):
    l = l or []
    print(l)

l = l or [] という処理で、 l が偽の場合(例えば None の場合)に [] を設定するという処理ができます。 or 演算子は、左が偽であれば右の値を返すという動作をするからです。

and, orを3つ以上で使う

さらに、発展してブール演算が3つ続いた場合を考えましょう。 3つ以上の場合も、順に分解していくと分かりやすいでしょう。

string1 = ''
string2 = 'Trondheim'
string3 = 'Hamer Dance'
non_null = string1 or string2 or string3
print(non_null)  # 答えは Trondheim になります

まず、 string1 or string2 の部分が、以下のように評価されます

'' or 'Trondheim'

ここで or の左が偽なので、結果は右の 'Trondheim' となります。 さらにこの 'Trondheim' と、残りの or が評価されます

'Trondheim' or 'Hamer Dance'

ここで or の左が真なので、結果は変わらず 'Trondheim' となります。 なので、 '' or 'Trondheim' or 'Hamer Dance' の結果は 'Trondheim' となります。

この動作の利点

このように左の結果を見て動作することで、無駄な処理を排除できる利点があります。 例えば以下のようなプログラムがある場合、 or の左の can_edit() 関数の結果が True であれば右の関数 can_publish()実行されなくなります

if can_edit() or can_publish():
    ...

or は、左の結果が真の場合にその結果を返すので、 or の右の処理が実行されません。 なので、不用意に can_publish() 関数が実行されないという利点があります。

生真面目に or の左と右を評価してから TrueFalse を決めていると、無駄な処理を実行してしまう可能性があるからです (左が真の時点で、右が何であろうと or の結果は真なので)。

まとめ

今回紹介したポイントは3つです。

  • andor は真偽を元に左か右の値を返す処理をする
  • andor はブール値以外にも使える
  • andor はif文以外でも使える

知っておけば andor をうまく使った処理を見たときに、困ることはないでしょう。

プログラミング言語というのは、よくできていてすごく美しいものだなぁと思います。

Copyright ©2017-2018 BeProud Inc. All rights reserved.