Pythonで条件分岐やループを書くとき、必ず出てくるのが「真(True)」と「偽(False)」という概念です。
これらを値として扱うのがブール型(bool
)で、比較や論理演算の結果としても返されます。
本稿では、bool
の定義から真偽の判定ルール、演算子のふるまい、よくある落とし穴と実用パターンまで、実践的に解説します。
Pythonのブール型(bool)とは?True・Falseの基本
ブール型(bool)の定義と用途(真偽値の意味)
ブール型は、論理の二値「真(True)」と「偽(False)」を表すための型です。
条件分岐、ループ、比較演算の結果、フィルタリング、テストなど、Pythonプログラミングのあらゆる場面で用いられます。
if
やwhile
の条件には「ブール式」(評価するとTrue
またはFalse
になる式)を置くのが基本です。
例:ブール値の基本
# True と False は bool 型の2つの単一の値
print(True, False)
print(type(True), type(False))
# 比較演算は bool を返す
print(3 < 5, 10 == 2 * 5, "py" in "python")
True False
<class 'bool'> <class 'bool'>
True True True
True と False の表現と大文字小文字の注意
True
とFalse
は予約語に準じる定数で、頭文字が大文字です。
小文字のtrue
やfalse
は存在しません(未定義名としてNameErrorになります)。
ブールリテラルは必ず先頭大文字で書きます。
# 正しい例
flag = True
# 間違い: NameError になる
# flag = true
bool は int のサブクラス:True は 1、False は 0
Pythonではbool
はint
のサブクラスです。
そのため、True == 1
、False == 0
となり、算術演算にも参加します。
ただし、意味が紛らわしくなるため、意図しない数値用途としての利用は避けるのが無難です。
# bool は int のサブクラス
print(issubclass(bool, int)) # 継承関係
print(isinstance(True, int)) # True は int としても扱われる
# 数値としてのふるまい
print(True == 1, False == 0)
print(True + True, True * 10, 3 * False)
# 集計に使える(例: 条件に合致した要素数を数える)
data = [10, -3, 7, 0, 5]
num_positive = sum(x > 0 for x in data) # True が 1 として数えられる
print(num_positive)
True
True
True True
2 10 0
3
真偽値の判定と「真/偽」とみなされる値のルール
False と評価される値:0、0.0、”、[]、{}、set()、None など
Pythonでは、ブール型そのもの以外にも、オブジェクトが「真」と「偽」のどちらかとして評価されます。
代表的に「偽」と評価されるのは以下です。
カテゴリ | 値または例 | 説明 |
---|---|---|
数値 | 0 , 0.0 , 0j , Decimal(0) , Fraction(0, 1) | 0は偽 |
文字列・バイト列 | '' , b'' | 空は偽 |
コンテナ | [] , () , {} , set() , range(0) | 空は偽 |
特殊値 | None , False | それ自体が偽 |
ユーザー定義 | __bool__ がFalse 、または__len__ が0 を返す | カスタム型の規約 |
それ以外は原則「真」とみなされます。
bool() による型変換と真偽値の評価
bool(x)
で値の真偽を明示的に評価できます。
# 代表例の真偽評価
samples = [0, 1, -1, 0.0, 0.1, '', '0', [], [0], {}, {'a': 1}, set(), None, False, True]
results = {repr(x): bool(x) for x in samples}
for k, v in results.items():
print(f"{k:>8} -> {v}")
# カスタムクラスの真偽: __len__ または __bool__ を定義
class Box:
def __init__(self, items):
self.items = items
def __len__(self): # 要素数0なら偽、それ以外は真
return len(self.items)
print(bool(Box([])), bool(Box([1])))
0 -> False
1 -> True
-1 -> True
0.0 -> False
0.1 -> True
'' -> False
'0' -> True
[] -> False
[0] -> True
{} -> False
{'a': 1} -> True
set() -> False
None -> False
False -> False
True -> True
False True
比較演算子と論理演算子の使い方(真偽値を返す式)
比較演算子 ==, !=, <, <=, >, >= の基本
比較演算はbool
を返します。
Pythonは比較の連鎖(連結)もサポートしており、0 < x < 10
のように自然な書き方ができます。
x = 7
print(x == 7, x != 7, x < 10, x <= 7, x > 3, x >= 8)
print(0 < x < 10) # 連鎖比較: (0 < x) and (x < 10) と等価
True False True True True False
True
比較は型に注意
異なる型間の比較は原則として意味のある場合のみ許可されます(例えば数値同士はOK、数値と文字列はエラー)。
print(5 == 5.0) # True(数値として等価)
# print(5 < '5') # TypeError: 数値と文字列は比較できない
True
論理演算子 and, or, not の評価順序と短絡評価(ショートサーキット)
演算子の優先順位は「not > and > or」です。
また、and
とor
は「短絡評価」を行い、必要最小限のオペランドしか評価しません。
さらに、これらは最後に評価した“元の値”を返すため、必ずしもbool
を返すとは限りません。
def probe(name, result):
print(f"probe({name}) -> {result}")
return result
# 優先順位: not > and > or
expr = not False or False and True # = (not False) or (False and True) = True or False = True
print(expr)
# 短絡評価のデモ
print("A and B:")
res1 = probe("A", False) and probe("B", True) # AがFalseならBは呼ばれない
print("result:", res1)
print("C or D:")
res2 = probe("C", True) or probe("D", False) # CがTrueならDは呼ばれない
print("result:", res2)
# “そのままの値”を返す
print([] or [1, 2, 3]) # 左が偽([])なので右を返す
print("X" and 42) # 両方真 -> 右オペランドが返る
print(0 and 99) # 左が偽(0) -> 左が返る
True
A and B:
probe(A) -> False
result: False
C or D:
probe(C) -> True
result: True
[1, 2, 3]
42
0
is と == の違い(同一性と等価性)
==
は「等価性(値が等しいか)」を比べます。is
は「同一性(同じオブジェクトか)」を比べます。
is
は主にNone
との比較や、同一オブジェクト判定に使います。
値の比較には==
を使います。
a = [1, 2]
b = [1, 2]
c = a
print(a == b, a is b) # 値は等しいがオブジェクトは別
print(a is c) # 同じオブジェクト
# 文字列の例(インターン最適化の影響を受けることがある)
s1 = "abc"
s2 = "".join(["a", "b", "c"])
print(s1 == s2, s1 is s2) # 等価だが、同一とは限らない
# None は is で比較する
x = None
print(x is None, x == None) # 後者は動くが推奨されない
True False
True
True False
True True
条件分岐・ループでのブール値の活用
if, elif, else での真偽値の使い方
if
文ではブール式を評価して分岐します。
空のコンテナやNone
は偽とみなされます。
name = "Alice"
items = []
if name and not items:
print(f"{name} さん、カートは空です。")
elif items:
print(f"{name} さん、{len(items)}点入っています。")
else:
print("ゲストさん、ログインしてください。")
Alice さん、カートは空です。
while ループの条件とブール式
while
は条件がTrue
の間繰り返します。
n = 3
while n:
print("n =", n)
n -= 1
print("done")
n = 3
n = 2
n = 1
done
三項演算子(条件式)による値の選択
PythonではA if 条件 else B
と書きます。
score = 78
label = "PASS" if score >= 60 else "FAIL"
print(label)
PASS
よくある落とし穴とベストプラクティス
if x == True を避け、if x を使う理由
if x == True:
は冗長で、x
がブール以外の型の場合に意図せずFalse
になることがあります。
基本は単にif x:
と書きます。
# 良い例
flags = [True, False, True]
if all(flags):
print("すべて真です")
# 悪い例(冗長): if x == True は避ける
x = 1
print(x == True) # True だが、型によっては意図せず False になることも
print(bool(x)) # 真偽として評価したい場合はこちら
すべて真です
True
True
空コレクション・None の判定の書き方
空であるかの判定は長さ比較ではなく、真偽で判定します。
None
の判定はis
を用います。
items = []
config = None
# 空の判定
if not items:
print("空です")
# None の判定
if config is None:
print("設定がありません")
# 悪い例: if len(items) == 0: や if config == None: は避ける
空です
設定がありません
浮動小数点の比較と真偽値の注意点
浮動小数点は丸め誤差があるため、直接==
で比較しないのが原則です。
math.isclose()
などを使います。
import math
x = 0.1 + 0.2
print(x == 0.3) # 期待に反して False
print(math.isclose(x, 0.3, rel_tol=1e-9, abs_tol=0.0)) # 許容誤差内なら True
False
True
実用パターン:any/all、フィルタリング、内包表記とテスト
any() と all() で複合条件を簡潔に書く
any(iterable)
は一つでも真があればTrue
、all(iterable)
はすべて真ならTrue
です。
ジェネレータ式と組み合わせると効率よく短絡評価します。
scores = [72, 85, 90, 58]
# すべて60点以上か?
print(all(s >= 60 for s in scores))
# 一つでも不合格があるか?
print(any(s < 60 for s in scores))
# ネストした条件の例
users = [{"name": "A", "active": True}, {"name": "B", "active": False}]
print(any(u["active"] for u in users))
False
True
True
filter() と内包表記でのブール式の活用
条件に合う要素を抽出するには、filter()
か内包表記を使います。
filter(None, iterable)
やfilter(bool, iterable)
は偽の要素を取り除くイディオムです。
data = [0, 1, "", "ok", [], [1], None, True, False]
# 偽の要素を除外
cleaned = list(filter(bool, data))
print(cleaned)
# 条件で抽出(内包表記)
nums = [-2, -1, 0, 1, 2, 3]
positives = [n for n in nums if n > 0]
print(positives)
# dict のフィルタリング
d = {"a": 1, "b": 0, "c": 2}
nonzero = {k: v for k, v in d.items() if v}
print(nonzero)
[1, 'ok', [1], True]
[1, 2, 3]
{'a': 1, 'c': 2}
assert とユニットテストでの真偽値の使い方
日常的なチェックにはassert
、体系的なテストにはunittest
などのフレームワークでassertTrue
/assertFalse
を使います。
# 事前条件チェックに assert
def divide(a, b):
assert b != 0, "b は 0 以外である必要があります"
return a / b
print(divide(10, 2))
# print(divide(10, 0)) # AssertionError
5.0
# 簡単なユニットテスト
import unittest
def is_even(n: int) -> bool:
return n % 2 == 0
class TestIsEven(unittest.TestCase):
def test_even(self):
self.assertTrue(is_even(2))
self.assertTrue(is_even(0))
def test_odd(self):
self.assertFalse(is_even(1))
self.assertFalse(is_even(-3))
if __name__ == "__main__":
unittest.main(exit=False) # Jupyter等での実行用
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
まとめ
ブール型bool
はPythonにおける意思決定の要であり、True
/False
のみならず「真偽として解釈される値」の体系に支えられています。
bool
がint
のサブクラスであることは便利な一方で、意図しない数値的解釈を招くこともあるため文脈に注意が必要です。
論理演算子の優先順位と短絡評価、is
と==
の違い、空コレクションやNone
の判定、浮動小数点比較の扱いなどを押さえると、条件分岐やループ、フィルタリング、テストまで、より安全で読みやすいコードが書けます。
any
/all
、内包表記、assert
やユニットテストと併せて、真偽値の扱いを自分のコーディング標準に取り入れていきましょう。