
Table of Contents(目次)
Pythonのbool型とは?TrueとFalseの基本
これまで、True
, False
をif文などで使用してきましたが、このレクチャーでは、それらの仕組みをもう少し掘り下げて解説します。
if文のように条件によって処理を分岐させるものは、その条件が正しい(真/True
)か正しくない(偽/False
)かによって、次の処理の流れが決まります。
bool
型の値は、True
, False
の2つのみです。
# bool
True
False
Pythonの比較演算子まとめ(==, !=, <, >, <=, >=)
Pythonの比較演算子の意味と使い方
a == b
- aとbの値が同じかどうかを調べます: 同じならば
True
=
は値の代入、==
は両辺の値の比較になります- 初心者が特に間違えやすいポイントです
- 数値の場合は、intとfloatとで型が違っても、同じ値とみなされれば
True
になります1 == 1.0
はTrue
になります- ただし、
1 == '1'
のように数値と文字列を比較する場合はFalse
になります
- 文字列の場合、文字の生成手順によってid()の結果が変わる場合がありますが、文字の並びが同じであれば
True
になります- 文字列は、大文字と小文字を区別します
- aとbの値が同じかどうかを調べます: 同じならば
str1 = 'ABC'
str2 = f"A{'B'}C"
print(str1, id(str1)) # 'ABC' 2265151374416 (idは違う)
print(str2, id(str2)) # 'ABC' 2265158076096 (idは違う)
print(str1 == str2) # 文字の並びが同じなので、True
a != b
- 両辺の値が異なるかどうかを調べます: 違えば
True
- 文字列は、1文字でも違えば
True
になります'apple' != 'Apple'
はTrue
(大文字小文字を区別)
- 両辺の値が異なるかどうかを調べます: 違えば
a < b
- aがbより小さいかどうかを調べます: aがbより小さければ
True
- 大小比較の演算子では、int/floatとstrの比較はできず、TypeErrorになります
- これは、
a <= b
,a > b
,a >= b
の場合も同様です
- これは、
- 数値では、数の大小で比較します
3 < 5
はTrue
5 < 3
はFalse
- 文字列でも比較はできますが、文字コード(Unicode)で割り振られている順序で判断されます
'a' < 'b'
はTrue
('a'の方がUnicode上の値は小さい)'A' < 'a'
はTrue
(大文字の方が先 (割り振られている番号が小さい))
- 文字列の比較は、辞書の索引順に近い動きをする点に注意しましょう
'apple' < 'banana'
はTrue
'apple' < 'Apple'
はFalse
- (
'A'
の Unicode 値は'a'
より小さいため、'Apple'
の方が「辞書順で前」に来ます。
したがって'apple' < 'Apple'
はFalse
になります。)
- (
- aがbより小さいかどうかを調べます: aがbより小さければ
a <= b
- aがbより小さいまたは等しいかを調べます: aがb以下なら
True
<
と==
の両方を含んだ条件です3 <= 5
はTrue
5 <= 5
もTrue
- 文字列の場合も同様に、文字コード順で比較されます
- aがbより小さいまたは等しいかを調べます: aがb以下なら
a > b
- aがbより大きいかどうかを調べます: aがbより大きければ
True
<
の逆の関係になります7 > 3
はTrue
3 > 7
はFalse
- 文字列の場合は、Unicode順で判断されます
'z' > 'a'
はTrue
'A' > 'a'
はFalse
- aがbより大きいかどうかを調べます: aがbより大きければ
a >= b
- aがbより大きいまたは等しいかを調べます: aがb以上なら
True
>
と==
の両方を含んだ条件です5 >= 5
はTrue
10 >= 2
はTrue
- 文字列の比較でも、同様にUnicode順を基準にします
- aがbより大きいまたは等しいかを調べます: aがb以上なら
a < x < b
0 < num <=10
のように、変数の値が一定の範囲内に収まっているかどうかを調べることもできます<
,>
,<=
,>=
(大小比較)の演算子を使うことができますが、通常は(コードの読みやすさからも)、<
と<=
の組み合わせで構成することになるでしょう
Pythonで比較可能なデータ型と不可能な例
等価比較 (== / !=)
異なる型でも比較は可能(ただし、意味のある結果になるとは限りません)。Pythonは、両辺の値が「等しいかどうか」を判定しようとしますが、型が違えば普通はFalse
になります。
大小比較(<, >, <=, >=)
異なる型では比較できません(Python 3ではエラーになります)。特に、数値と文字列の大小比較は「意味がない」と判断され、TypeErrorが発生します。
同じ型同士であれば比較可能です:
- 数値同士(
int
,float
,Decimal
など) - 文字列同士(Unicode順で比較)
演算子 | 型が違っても比較できるか | 例 (1 vs '1' ) | 結果またはエラー |
---|---|---|---|
== | できる(Falseになる) | 1 == '1' | False |
!= | できる(Trueになる) | 1 != '1' | True |
< | できない(エラー) | 1 < '1' | TypeError |
<= | できない(エラー) | 1 <= '1' | TypeError |
> | できない(エラー) | 1 > '1' | TypeError |
>= | できない(エラー) | 1 >= '1' | TypeError |
Pythonの真理値(Truth Value)の判定方法
PythonのTrueとFalseは整数としても使える
まず、次のコードを見てください。
int(True) # 1
int(False) # 0
True == 1 # True
False == 0 # True
Pythonでは、True
やFalse
を整数に変換すると、True
は1
、False
は0
として扱われます。つまり、整数値の1
と0
はboolとしても扱われます。
たとえば次のようなコードを書いても動きます。if 1:
はTrue
に、if 0:
はFalse
になります。
# True
if 1:
print('True')
else:
print('False')
# False
if 0:
print('True')
else:
print('False')
Pythonのすべてのオブジェクトの真偽値判定
Pythonでは、どのオブジェクトも、True
/ False
を判定できます。数値だけでなく、文字列やlist、dictなどでも真偽を判定できます。次のコードでは、変数greetingの値('Hello'
)は「空でない文字列」なので、True
と同じように扱われます。したがって「Trueと判定される」と表示されます。
greeting = 'Hello'
if greeting:
print('Trueと判定される')
PythonでFalseと同じように扱われる値一覧
まずは、False
と同じように振る舞う値を覚えましょう。なぜなら、False
として扱われるパターンは少ないからです。
False
のように振る舞うデータには、「値がゼロ」「中身が空」「存在しない(None)」という共通点があります。
# False
0
0.0
'' # 空文字
[] # 要素を持たないlist
{} # 要素を持たないdict
tuple() # 要素を持たないtuple
set() # 要素を持たないset
None # None (何も存在しないことを明示的に表すデータ型)
PythonでTrueと同じように扱われる値一覧
上記以外の値はすべてTrue
として扱われます。「空でなければTrue
」、中身があることがポイントです。
つまり、listなどのデータ構造の場合は、要素(中身)が存在していれば、値が0
やNone
であってもTrue
になります。重要なのは「空でないこと」です。
# True
1
-1
0.0001
-0.0001
'0' # どんな文字であっても、1文字以上の文字列
' ' # 空白も、True
[None] # 要素の中身が 0 や None、空文字でも、list自体が空でなければ True (以下の例も同様に、要素が存在すればTrue)
{0: None}
(0,)
{0}
具体的な使いどころとして、たとえば「listの要素が存在していればpop()
する」といった場面を考えてみましょう。pop()
は要素が存在しない時はエラーを発生させるため、安定的にプログラムを実行させるために、事前に要素の有無を確認しておくことが重要です。
if len(num_list) > 0:
のように、『要素数が0より大きければ処理を行う』というような書き方もできますが、それよりもif num_list:
のように記述した方がシンプルで可読性も向上します。この時、変数num_list
の要素数が0
だった場合はif文のブロックは処理されず、要素が1つ以上存在している時のみ処理されます。
num_list = [1, 2, 3]
# listの要素が存在していれば、popする
if num_list:
result = num_list.pop()
print(num_list)
print(result)
Pythonのnot演算子の使い方
not
は、条件の「反対」を表す演算子です。True
をFalse
に、False
をTrue
に変えます。
a = True
print(not a) # False
b = False
print(not b) # True
not
を使うと、条件を反転させて「〜でなければ」という形にできます。例えば、次のコードは、『listの要素がなければ、要素を追加する』という処理を行っています。
num_list = []
# listに要素が無ければ、要素を追加する
if not num_list:
num_list.append(None)
print(num_list)
Pythonのin/not in演算子で要素の有無を判定
a in b
, a not in b
のように記述し、a
がb
の中に「含まれている(in
)」か「含まれていない(not in
)」かを調べます。
Pythonで文字列のin/not in判定方法
文字列では、部分文字列として含まれているかを判定します。これは、大文字と小文字を区別します。
例えば、'can' in 'I can do it.'
というコードは、'can'
の文字の並びが'I can do it.'
の文字列の中に含まれているかどうかを調べ、含まれていればTrue
になります。
text = 'I can do it.'
print('can' in text) # True ('can'は含まれる)
print("can't" not in text) # True ("can't"の文字の並びは含まれないのでTrue)
Pythonでlist, tuple, set内の要素確認
list, tuple, setの場合は、要素の中に値が存在するかを判定します。
num_list = [1, 2, 3]
print(1 in num_list) # True
print(4 in num_list) # False
print(1 not in num_list) # False
print(4 not in num_list) # True
Pythonでdict内のkey・valueの存在確認
dictでは、keyの存在を調べます(値は対象になりません)。ただし、dict.values()
でvalueを取得した後で、値が含まれているかどうかを調べることはできます。
# keyの有無を調べる
tmp_dict = {'key1':100, 'key2':200}
print('key1' in tmp_dict) # True
print(100 in tmp_dict) # False (100というkeyは存在しない)
print('key1' not in tmp_dict) # False ('key1'のkeyは存在するので、[not in]はFalseになる)
print(100 not in tmp_dict) # True (100というkeyは存在しないのでTrue)
# valueの有無を調べる
tmp_dict = {'key1':100, 'key2':200}
print(100 in tmp_dict.values()) # True (valueに100が存在する)
print(500 not in tmp_dict.values()) # True (500というvalueは存在しない)
Pythonのis/is not演算子の使い方
is
は「同じデータ(オブジェクト)を参照しているかどうか」を確認します。==
の「値が同じかどうか」を比較する点と異なります。
同じ値でも異なるオブジェクトの判定
次のコードの、変数aとbは見た目の値は同じ('ABC'
)ですが、id()
を調べてみると、違う場所に保存されたデータを参照していることがわかります。
この時、==
はTrue
になりますが、is
はFalse
になります。ですので、"値"を調べたいのか、"参照先"を調べたいのかで、==
とis
を使い分けます。
a = 'ABC'
b = f"{'A'}{'B'}{'C'}"
id(a) # 例: 139982392668688
id(b) # 例: 139979347634776
a == b # True 値が同じだから
a is b # False 参照先(オブジェクト)が違うから
同じオブジェクトを参照している場合
b = a
のように、同じオブジェクトを参照させるようにすると、is
はTrue
を返します。
b = a
id(a) # 例: 139982392668688
id(b) # 例: 139982392668688 (aと同じ)
a == b # True 値が同じ
a is b # True 同じデータを参照している
Pythonのis not演算子の使い方
is not
は、「同じオブジェクトではない」という意味になります。
x = [1, 2, 3] # id例: 2066161843712 (異なるid)
y = [1, 2, 3] # id例: 2066161828672 (異なるid)
x == y # True 値は同じ
x is y # False 別のリストを参照
x is not y # True 同じオブジェクトではないのでTrue
Pythonのand / or論理演算子の使い方
andの動作と評価順序
and
は、『両方の条件がTrue
の場合のみ』、True
になる論理演算子です。
例えば、次のようなコードを考えます。
num = 5
if num > 0:
if (num % 2) == 1: # [num % 2]の結果(除算の余り)が"1"なら奇数である
print('正の数 & 奇数') # num=5 の場合、出力されます
上記コードは、変数numの値が正の数で、かつ奇数の場合にprint('正の数 & 奇数')
が実行されます。これと同じ処理をand
を使って1行で書くと、次のようになります。
num = 5
if (num > 0) and ((num % 2) == 1):
print('正の数 & 奇数') # num=5 の場合、出力されます
上記コードのように、各条件式を丸カッコで囲わなくても、条件の評価は問題なく動作します。Pythonでは演算子の優先順位が決められており、上位の演算子から優先的に評価が行われるため、if num > 0 and num % 2 == 1:
のように記述しても、意図した通りに判定されます。
しかし、丸カッコで囲っておくと、どの条件とどの条件をand
で演算しているのかが分かりやすくなるので、可読性向上のために筆者は丸カッコを使ってコードを書くようにしています。
※ 当然ながら、Pythonのデフォルトの優先順位と異なる順に計算(評価)を行いたい場合は、丸カッコで優先順位をコントロールする必要があります。
演算子 | 説明 |
---|---|
(expressions...) ,[expressions...] ,{key: value...} , {expressions...} | 結合式または括弧式、リスト表示、辞書表示、集合表示 |
x[index] , x[index:index] ,x(arguments...) , x.attribute | 添字指定、スライス操作、呼び出し、属性参照 |
await x | Await 式 |
** | べき乗 [5] |
+x , -x , ~x | 正数、負数、ビット単位 NOT |
* , @ , / , // , % | 乗算、行列乗算、除算、切り捨て除算、剰余 [6] |
+ , - | 加算および減算 |
<< , >> | シフト演算 |
& | ビット単位 AND |
^ | ビット単位 XOR |
| | ビット単位 OR |
in , not in , is , is not ,< , <= , > , >= , != , == | 所属や同一性のテストを含む比較 |
not x | ブール演算 NOT |
and | ブール演算 AND |
or | ブール演算 OR |
if -- else | 条件式 |
lambda | ラムダ式 |
:= | 代入式 |
and
の評価は次のように行われます。
- 左側の条件が
False
の場合、右側の条件は確認されずに結果はFalse
になります - 両方
True
の場合のみTrue
となります
print(True and True) # True (両方の条件が確認される)
print(True and False) # False (両方の条件が確認される)
print(False and True) # False (左側の条件がFalseなので、右側の条件は確認されない)
print(False and False) # False (左側の条件がFalseなので、右側の条件は確認されない)
orの動作と評価順序
or
はどちらか一方がTrue
ならTrue
になります。両方False
の場合のみFalse
です。
- 左側が
True
の場合、右側は確認されずにTrue
が返されます - 左側が
False
の場合、右側の条件を確認してTrue
かFalse
を返します
print(True or True) # True (左側の条件がTrueなので、右側の条件は確認されない)
print(True or False) # True (左側の条件がTrueなので、右側の条件は確認されない)
print(False or True) # True (両方の条件が確認される)
print(False or False) # False (両方の条件が確認される)
and と or の組み合わせ例
例として、スポーツクラブを利用できる条件を考えます。
- 会員である または
- 18歳以上 かつ 1日利用料金を支払済み
この条件をPythonで書くと次のようになります。
# 利用者情報
person = {
'member': True,
'age': 18,
'paid': True
}
# 利用可能か判定
if person['member'] or (person['age'] >= 18 and person['paid']):
print('スポーツクラブを利用できます')
else:
print('利用できません')
member
がTrue
の場合、右側の条件は確認されずに利用可能になりますmember
がFalse
の場合、右側の条件(age >= 18 and paid)
が評価されます
and
とor
が混在する場合、丸カッコを使ってコードを整理すると、条件の評価順が分かりやすくなります。
なお、条件が長くなる場合は、改行して記述できます。改行させながら記述したい時は、条件全体を丸カッコで囲います。
(if a or b and c:
-> if (a or b and c):
)
if (person['member'] or
(person['age'] >= 18 and person['paid'])):
print('スポーツクラブを利用できます')
このように、条件全体を丸カッコで囲うことで、改行して条件を書いても正しく評価されます。また、可読性も向上します。
なお、改行した条件の部分(上記コードの2行目)のインデントについては、厳密なルールはなく、スペース4つでも構文としては問題ありません。しかし、スペース4つにすると、ブロック内のコードと見分けが付きにくくなってしまいます。
if (person['member'] or
(person['age'] >= 18 and person['paid'])): # この行と次の行のインデントが同じ
print('スポーツクラブを利用できます')
そのため、PythonのPEP 8(Code Lay-out)では、スペース8つ(インデント2個分)にすると可読性が向上するとされています。(もしくは、ブロックの先頭にコメントを付けることで条件文とブロックを隔てることができるとしています。)
if (person['member'] or
(person['age'] >= 18 and person['paid'])): # インデント2つ分にする
print('スポーツクラブを利用できます')
if (person['member'] or
(person['age'] >= 18 and person['paid'])):
# コメント(ブロックに関する説明文など)を入れて、条件文とブロックを隔てる
print('スポーツクラブを利用できます')