読者です 読者をやめる 読者になる 読者になる

へっぽこびんぼう野郎のnewbie日記

けろけーろ(´・ω・`)!

pythonで(a and b) or cがif else文のようになる理由と、これをあまり使わないほうがいい理由

*1

 

aがFalseだ、bも判定しよう

bもFalseだ。c and dも判定しよう

c and dはさっき判定したやつでdだった、

a or b or c and d # => d

 

hoge and ~~~

のときは、hogeがTrueなら次を判定して

Falseならそのままそれを出力

 

moge or ~~~

のときは、mogeがTureならそれをそのまま出力して

Falseなら次を判定する

 

って感じ。

 

冒頭のはこんなふうにも書ける(ド・モルガンの公式)

誰もこんなふうには書かないけど

 

not *2 or f)) or g

 

(a and

    *3

    or f))

or g

 

みたいな感じか。

わかりにくすぎる。

 

応用編2

 

if a:

    b

elif c:

    d

else:

    e

 

 

(a and b) or (c and d) or e

 

冒頭に、だいたい等価と書いた理由は

(a and b) or cは

bがFalseのとき機能しないし、

(例えばこれ。)

a = 1

print (a < 3 and 0) or 5

# => 5

 

他にも、

 

a = 1

def b():

    print "b"

def c():

    print "c"

 

(a < 3 and b()) or c()

 

こういう場合も全然機能してくれない。

b

c

と表示される。

これってなんでSyntax errorにならないのか謎なんだけど偉い人教えてください。

ていうか、なんでbもcも表示されるのか意味不明すぎて困る。

 

print (a < 3 and "b") or "c"

 

なら思ったとおりに通る。

 

参考書にも、「if else文に 近い 構文が書ける」と書いてあることから

この書き方が不都合なことは、どうやら周知の事実らしいが、

こうやって書けることだけ論って、その大きなデメリットがどこにも書かれていないことが気になった。

 

とりあえずわかりやすいif else文を書くように心がけようって思った。

*1:a and b) or c)

 

意味:

    b if a else c や

 

    if a:

        b

    else:

        c        とだいたい等価

 

それってなんでなのかについて。

まず、andやorがかかわってきたときの出力の仕組みについて説明する。

 

これにザッと目を通して欲しい。

 

print 1 # => 1 

print 2 # => 2  

print 1 and 2 # => 2

print 1 or 2 # => 1

print 0 or 2 # => 2

print 2 or 0 # => 2

print False or 1 # => 1

print True or 1 # => True

print 1 or True # => 1

 

これがどういうことかと言うと、

andやorは、TrueかFalseかを判定して表示してくれているということ。

まず、大前提として、数字は0じゃなかったらTrueだし、文字は文字があればTrue

 

「真」になったよーってわかった段階のヤツを表示する。

以下解説

 

print True and True # => True

 

1つ目はTrue、2つ目はどうかな。2つ目もTrue、だから True and TrueはTrueだよ

 

print True and false # => False

 

1つ目はTrue だから2つ目を調べるよ。2つ目はFalseだったよ。だからTrue and FalseはFalseだよ

 

print True or True # => True

 

1つ目がTrueだったよ。だからorの後ろが全部Falseでも全然関係なくTrue or True はTrueだよ

 

print True or False # => True

 

1つ目がTrueだったよ。だからorの後ろが全部Falseでも全然関係なくTrue or FalseはTrueだよ

 

print False and False # => False

 

1つ目がFalseだったよ。だからandの後ろが全部Trueでも全然関係なくFalse and FalseはFalseだよ

 

print False and True # => False

 

1つ目がFalseだったよ。だからandの後ろが全部Trueでも全然関係なくFalse and TrueはFalseだよ

 

print False or True # => True

 

1つ目がFalseだったよ。2つ目はどうかな。Trueだ。だからFalse or TrueはTrue

 

print False or False # => False

 

1つ目がFalseだったよ。2つ目もFalseだったよ。じゃあFalse or FalseはFalseだね

 

という話。

たぶん2つだからよくわかりにくいし、TrueやらFalseがたくさん出てくるからもっとわかりにくい。。

 

コンピュータの判定の仕方を考えるとわかりやすいかも。

a,bはTrue、cはFalseのとき、(dはどっちでもいい)

 

a and b and c and d

 

aがTrueだ、bも判定しよう

bもTrueだった。cも判定しよう

cはFalseじゃねーか! やってられるか! -> c

みたいな感じ。

 

次はこれ

a,b,dがFalse、cだけTrueのとき、

 

a or b or c and d

 

この場合、andの方を先に判定する。掛け算と足し算チックな優先方法。

cがTrueだ、dも判定しよう

dがFalseじゃねーか! やってられるか! (c and dに関して)-> d

((蛇足:もしdがTrueでも、同じようにc and dの結果はdになる、

*2:not a or not b) and not c)

not (not a or not b) or not not c

 

応用編

if a:

    if b:

        if c:

            d

        else:

            e

    else:

        f

else:

    g

 

 

(a and ((b and ((c and d) or e

*3:b and

        ((c and

            d)

        or e