Be a Pythonista ! その5 条件分岐②

注:本記事は比較的がちふぁい勢向けかもしれません。


目次



前の記事

この記事は続き物なので、良ければひとつ前の記事もどうぞ!


条件分岐の「条件」は多種多様

前回記事で言及した通り、if文そのものの使い方は極めて簡単です。

  • if ○○:

  • elif ○○:

  • else:

上記の三つがif文の全てです。

でも、実は本当に大切なのは「○○」の部分だったりします。
○○は、TrueかFalseであれば条件分岐として機能しますが、
Pythonくんが何を「True」とし、何を「False」とするのか。
これがわりとバリエーション豊富なんです。

この記事では○○についてちょっとだけ首を突っ込みます!


もっともシンプルな条件

まず最初にシンプルな条件を設定してみましょう。

条件が成立するパターン

  • if True:

  • if not False:

  • if True and True:

  • if True or False:

  • if False or True:

条件が成立しないパターン

  • if False:

  • if not True:

  • if True and False:

  • if False and True:

  • if False or False:

bool値をそのまま入れるのが一番シンプルな条件ですね。
たとえば、以下のようなコードです。

import cv2 as cv


def main():
    cap = cv.VideoCapture(0)

    while True:
        ret, frame = cap.read()
        if not ret:  # ここでつかってる。
            break

        cv.imshow('window', frame)
        key = cv.waitKey(1) & 0xFF
        if key == ord('q'):
            break

    cap.release()
    cv.destroyAllWindows()
        
if __name__ == '__main__':
    main()

上記はPCに接続されたWEBカメラの映像を表示するコードです。
OpenCVライブラリを用いていますが、今回はその辺は割愛します。

ret, frame = cap.read()

この部分で、retにカメラからのデータが正常に取得できたかどうかを
bool値で格納してくれています。
frameにはカメラの実際の映像(フレーム)データが格納されています。

データが正常に取得できていれば、
ret = True
取得できていなければ、
ret = False
となるのです。

つまり、

if not ret:
    break

上記の条件は、
正常に取得できた場合、
not ret = not True = False
となって、分岐後の処理には進みません。
取得できていなかった場合、
not ret = not False = True
となって、分岐後の処理に進みます。


値の比較

二つの値を比較して、真偽を見る場合が最も多い用法でしょう。

ただ、数値の比較は前回の記事で触れているので、
今回は数値以外の値を比較してみましょう。

script = 'Reala'  # Reala を値として持つ変数scriptを宣言

if script == 'Nayose':
    print(script, 'Reala')
elif script == 'Reala':  # この条件がTrueとなる
    print('Nayose', script)
else:
    print('だれだおめぇ?')

上記のコードだと、scriptの値は「Reala」なので、
二つ目の条件がTrueとなり、処理が実行されます。
このように、文字列同士が同じかどうかも比較することができます。
数値と文字列だけでなく、他の型の値でも比較演算子の右辺と左辺で比較
することが可能です。

たとえば、

x = [1, 2, 3]
y = [1, 2, 3]

if x == y:
    print('xとyは同じリスト!')

このように、リスト型同士の比較もできます。


オブジェクトの比較

値以外にもオブジェクトを比較して真偽を見ることもできます。

オブジェクトってなんぞや?
と思うかもしれませんが、ここで深く解説はしません。
とりあえず、「値ではない物」を比較する場合だと思ってください。

x = None
y = [1, 2, 3]

if x is None:
    print(x)

if type(y) is list:
    print(y)

上記の例だと、xにはNoneが、yにはリスト型の値が格納されています。
Noneは値のように感じるかもしれませんが、実際にはこれは値ではなく
Noneというオブジェクトなのです。
また、yはリスト型ですが、「リスト型」は「」ではありませんよね?

このように値以外の物は比較演算子を用いて比較することは、
Pythonではあまり良しとされません。
ただ、先ほどの例の「is」を「==」にしても動くには動きます。

もう少しいうと、型の比較でisを用いるのは特に問題ありませんが、
最善ではなかったりします。
場合によっては意図しない判定をすることがあります。
型の比較を行うのであれば、

y = [1, 2, 3]

if isinstance(y, list):
    print(y)

と書くのがおそらく最善だとげるすらは思っています。

他にも、クラス同士が同一であるかを判定する時もisを用います。


真偽値コンテキスト

急に必殺技みたいな名前が出てきました。
これも慣れればそんなに難しくありません。

真偽値コンテキストとは、簡単に言うと
こんな値はbool値に変換します!
とPythonくんが自動的に認識してbool値を返してくれるようなものです。
具体例が一番わかりやすいと思うので、コードを書いてみましょう。

x = ''
y = 'Reala'

if x:
    print('x is True')

if y:
    print('y is True')

この例だと、xには空文字列が、yには空ではない文字列が格納されてます。
そして、xとyをそのまま条件として用いています。

このような条件を書いた場合、xはFalseに、yはTrueに自動で変換されます
文字列の長さが0ならばFalse、1以上ならTrueになるのです。

他にも整数型で
x = 0
y = 1
のようにしても、xはFalse、yはTrueになります。

リスト型、タプル型、辞書型、セット型でも可能です。
x = []
y = [1]
これでも同じように、xがFalse、yがTrueと変換されます。

個人的に文字列や数値で真偽値コンテキストは使わない気がしますが、
リストなんかはそれなりに使う気がします。
例えば、

x = [1, 2, 3, 4, 5]

while x:
    item = x.pop(0)
    何かしら処理

if文ではありませんが、上記は真偽値コンテキストを用いてループ処理
を実行しています。
xのリストの中に要素が存在する限り処理を繰り返すコードです。

この例だと真偽値コンテキストを用いる必要性は皆無ですが、
ループ処理内で動的にリストの長さが増えたり減ったりして、
インデックスで値を指定するには複雑な時に有効な場合があります。

正直、真偽値コンテキストは慣れてきたら使う程度でいいと思いますし、
場合によってはコードの可読性を損なう場合もあるかもしれません。
使いどころには気をつけましょう!


条件分岐おわり!

条件分岐の「条件」の部分について書きましたが、
ここまでわかっていればまぁ困らないだろうと思います。

if文はコードを書いてたらかなり頻繁に書くことになると思いますので、
そのうち勝手に覚えます。
げるすらは最初そんな感じで覚えました笑
今なら紙でもなんでもコード書けますが、昔は紙とペンで書けと言われると何も書けなかったんですよね。
コード補完とハイライト機能に頼り切りでした。

たぶん、みんなそんな感じですよね!?
以上、蛇足でした。

ゆるふぁいです!


次の記事(予定)

アップしたらここにリンクを貼ります。
多分次は繰り返し処理をします。

この記事が気に入ったらサポートをしてみませんか?