今回の内容はプログラミング色が強めです。が、未経験者にも分かりやすく解説してまいります。
このシリーズでは、実は身近な話題に関連している IT(情報技術)を解説していきたいと思います。
ブール値とは
プログラミングにおける真か偽の値のことです。真理値、論理値、真偽値などとも呼ばれています。待って難しくないから帰らないナイデ。
まず、プログラミングでは、型 という概念を扱います。といっても大層なものではなく、これは数値、これは文字、これは日時のように、何を表す値であるかを明確にしておくといっただけです。表計算ソフトを使ったことのある方ならば、数値と文字列は別物だというイメージを持ちやすいかもしれません。あるいは、数学で「x は実数である」などと宣言するのにも近いかもしれません。
そして、真(true)または偽(false)を表すデータ型 (=ブール型,Boolean)の値のことを特にブール値と呼んでいます。要するに真か偽かのことです。例えば条件分岐をさせたい時などは、答えがブール値になるような式1を書き、その真偽に応じて分岐するプログラムを組んでやるわけです。
実例を挙げましょう。以下は実際に JavaScript2 において実行可能なプログラムです。
let x = 3; // x に 3 を代入する
if (x < 5) { // x が 5 未満なら
alert("This is true!"); // "This is true!" と表示する
}
JavaScriptここで注目してほしいのが3行目の括弧の中の部分です。今回はx < 5
という答えがブール値になる式を書き入れましたが、もしここに数値や文字列といったブール値以外の値を入れたらどうなるでしょうか。
当然ながら、これらはブール値ではないのでエラーが発生する…と言いたいところですが、多くのプログラミング言語ではこれを単なるエラーとして扱わず、都合が良い解釈で判定することになっています。
いくつか例を挙げましょう。以下は Python3 の仕様に従います。
真(true)と解釈される値
True
(ブール値)1
(数値)-999
(数値)"fuku"
(文字列)"木枯"
(文字列)"False"
(文字列)
偽(false)と解釈される値
False
(ブール値)0
(数値)""
(空文字列)[]
(空のリスト)set()
(空の集合)
True
やFalse
はそのままですね。0
が偽なのは、コンピューターの内部で真と偽をそれぞれ 1 と 0 で表現することに由来します。ですが、多くの言語では1
以外にも(0
を除く)すべての数値を真と扱うことが多いようです。現代でも 0 は特別な値ということでしょうか。
続いて、文字列についてですが、空文字(=0文字の文字列、表計算ソフトで未入力のセルに近い)は偽、それ以外はすべて真として扱います。つまり、文字列の"False"
も"偽"
も真なのです。直感に反するかもしれませんが、これは実例を考えると当然のことなのです。
まず、どんな時にプログラマーはこの文字列の真偽に依存するプログラムを書くでしょうか。例えば、ユーザーに名前を入力するように促し、名前がきちんと入力されていれば正常に処理を行い、なにも入力されていなければエラーメッセージを表示するといったプログラムを考えます。これを実際のプログラミング言語で書くと以下のようになります。
name = input("Enter your name> ") # ユーザーに名前を入力するように促す
if name != '': # もし名前が空文字でない(名前が入力された)とき
do_something() # なにか正常な処理を行う
else: # そうでなければ(名前が入力されていないとき)
print("Error! Name is not entered.") # エラーメッセージを表示する
Pythonここで3行目に注目してください。ここの条件name != ''
4は「名前が空文字でない」ことですが、これは前述の仕様によりもっと単純にname
と書けるのです。
name = input("Enter your name> ") # ユーザーに名前を入力するように促す
if name: # もし名前が空文字でない(名前が入力された)とき
do_something() # なにか正常な処理を行う
else: # そうでなければ(名前が入力されていないとき)
print("Error! Name is not entered.") # エラーメッセージを表示する
Python論理演算子
ちょいと話を脱線させて、次は論理演算子の話をしましょうか。名前がややこしいですが、要は我々が日常でよく使う「または」や「かつ」などのことです。英語で言うところの AND や OR などに相当しますね。
また Python で例を挙げましょう。Python では"または"をor
、"かつ"をand
で表現します。つまり以下の関係が成り立つわけですね
式 | 値 |
---|---|
False and False | False |
False and True | False |
True and False | False |
True and True | True |
and
式 | 値 |
---|---|
False or False | False |
False or True | True |
True or False | True |
True or True | True |
or
ではここで問題です。2 and 3
の値は何になるでしょうか。また、2 or 3
はどうでしょうか。
答え(クリックで開く)
2 and 3
は3
。また、2 or 3
は2
になる。
予想は合っていましたか?ちょっと意地悪でしたかね。でもこれにはちゃんと訳があるのです。
まずは前提となる、ある種当たり前の話をしましょう。
コンピューターはとても高速に計算を行いますが、それでも早いに越したことはありません。なので、無駄な計算はしたくありません。ここでA and B
が真、つまりA
とB
両者が真のときにのみ実行する処理Xがあるとします。ここで、B
の値を求めるのはとても大変で、できればやりたくないとしましょう。このとき、A
の値が偽であると分かったとしましょう。ならばB
の値をどうして求める必要がありましょうか。どうせA
が偽なら処理Xを実行することは無いのですから。この計算の省略のことをショートサーキットと呼んだります。
ここまでの話をまとめると、A and B
の内部処理は以下のように簡略化できそうです。
改良前
改良後
ここで改良後の「B が真である」の部分に注目してください。なんとB
の真偽とA and B
の真偽が一致しているではありませんか!よってさらに以下のように改良できそうです。(ついでに「B が偽である」の部分もそれに倣って修正。)
これが2 and 3
が3
になる理由です。2
は真ですから、B
である3
という値がそのまま帰ってきてしまっているのです。
同様の省略により、A or B
の内部処理は以下のようになっています。
時間がある方はA
とB
それぞれに真偽を入れて確かめてみてください。
ブール値を返す関数
では第二問目です。Python にはリストの中身すべてが真の時にのみTrue
になる関数all(iterable)
があります。いくつか動作の例を挙げましょう。
all([True, True, True])
→True
all([True, False, True])
→False
all([False, False, False])
→False
all([True])
→True
ではここで問題です。all([])
は真偽どちらでしょうか。要するに、空っぽのリストの中身はすべて真といえるでしょうか。
答えと解説(クリックで開く)
答えはTrue
です。「リストの中身すべてが真の時」は言い換えると「リストの中身に偽が一つも無いとき」です。あるいは、「ある集合がこの条件を満たすとき、その集合の部分集合もこの条件を満たす」という説明も出来るかもしれません。空集合は任意の集合の部分集合ですからね。