一覧へ

Truthy/Falsyとis vs ==

Pythonでどの値がTrue/Falseと評価されるのか、isと==の違いについて明確に説明します。

入門
|
8
|
検証済み (2026-07)
truthyfalsyis==None比較Python比較
進捗0/18 (0%)

Truthy/Falsyとis vs ==

このトピックを修了すると

Pythonにおいて、ある値が条件文でTrue/Falseとして評価されるかどうかを知り、is==を正しく使い分けられるようになります。


TruthyとFalsy

Pythonのif文は、True/Falseのみを受け付けるわけではありません。どんな値でも条件として使用できます。

python
if "hello":
print("実行される") # 実行される!
if 0:
print("実行されない") # 実行されない

Pythonはすべての値をTruthy(真とみなす)とFalsy(偽とみなす)に分けます。


Falsy値 — 覚えておけばOK

Falsyな値は決まっています。残りのすべてはTruthyです。

python
# これらがFalsy (Falseと評価)
False
None
0 # 整数0
0.0 # 浮動小数点数0
"" # 空の文字列
[] # 空のリスト
{} # 空の辞書
set() # 空のセット
python
# 確認してみる
values = [False, None, 0, 0.0, "", [], {}, set()]
for v in values:
print(f"{str(v):10} → {bool(v)}")
# False → False
# None → False
# 0 → False
# 0.0 → False
# → False
# [] → False
# {} → False
# set() → False

重要なルール:「空であるか、または0であればFalsy」。これだけ覚えていればOKです。


実践的なパターン — 空の値のチェック

Truthy/Falsyを活用すると、コードが簡潔になります。

python
# リストが空かどうかを確認
items = []
# こう書く必要はない
if len(items) > 0:
print("存在する")
# こう書けば良い
if items:
print("存在する")
python
# 文字列が空かどうかを確認
name = ""
if name:
print(f"こんにちは、{name}")
else:
print("名前を入力してください")
python
# Noneのチェックとデフォルト値
def greet(name=None):
name = name or "ゲスト"
return f"こんにちは、{name}"
print(greet()) # "こんにちは、ゲスト"
print(greet("太郎")) # "こんにちは、太郎"

or演算子は、左側がFalsyの場合に右側を返します。デフォルト値のパターンとしてよく使用します。


== — 値が同じか

==は、2つの値が等しいかどうかを比較します。

python
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True — 内容が同じなので

2つのリストは異なるオブジェクトですが、含まれている値が同じであるため、==Trueになります。

python
print(1 == 1.0) # True — 数値が同じなら
print("abc" == "abc") # True
print([1] == [1]) # True

is — 同じオブジェクトか

isは、2つの変数がメモリ上で同じオブジェクトを指しているかどうかを比較します。

python
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — 値は同じ
print(a is b) # False — 異なるオブジェクト
print(a is c) # True — 同じオブジェクトを指している

abは内容は同じですが、互いに異なるリストオブジェクトです。c = aは同じリストを指しているので、isTrueになります。

python
# id()で確認可能
print(id(a)) # 140234567890
print(id(b)) # 140234567920 (異なるアドレス)
print(id(c)) # 140234567890 (aと同じアドレス)

Noneの比較 — isを使うべき理由

python
result = None
# ✅ 正しい方法
if result is None:
print("結果なし")
# ❌ 推奨されない方法
if result == None:
print("結果なし")

NoneはPython全体で単一のオブジェクトです。isで比較することで、「これがまさにそのNoneオブジェクトか」を直接確認します。

==は、クラスが__eq__メソッドをオーバーライドすると、予想と異なる動作をする可能性があります。

python
class Tricky:
def __eq__(self, other):
return True # 何と比較してもTrue
t = Tricky()
print(t == None) # True — 危険!
print(t is None) # False — 安全

PEP 8(Pythonの公式スタイルガイド)でも、Noneの比較にはisを使用するように明示されています。


整数のキャッシュの罠

python
a = 256
b = 256
print(a is b) # True — CPythonが-5〜256を事前にキャッシュ
a = 257
b = 257
print(a is b) # False — 範囲外なので、別のオブジェクトを生成

CPythonは、小さな整数(-5〜256)を事前に作成しておき、再利用します。この範囲内ではisTrueになりますが、範囲外ではFalseになります。これが値の比較にisを使用すべきでない理由です。isは、NoneTrueFalseの比較にのみ使用します。

python
# 文字列でも同様の現象
a = "hello"
b = "hello"
print(a is b) # True — インターニングが発動
a = "hello world!"
b = "hello world!"
print(a is b) # False — 空白+特殊文字を含むと、インターニングされない

関数の引数のデフォルト値とNone

python
# ❌ 危険なパターン
def add_item(item, items=[]):
items.append(item)
return items
print(add_item("a")) # ["a"]
print(add_item("b")) # ["a", "b"] — 以前の呼び出しの結果が残っている!
# ✅ 安全なパターン
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items

可変オブジェクト(リスト、辞書)をデフォルト値として使用すると、すべての呼び出しが同じオブジェクトを共有します。Noneをデフォルト値として使用し、関数内で新しいオブジェクトを作成することが、Pythonの標準的なパターンです。


bool()とTruthy/Falsyの活用

python
# 空の値を簡潔に検証
data = {"name": "太郎", "email": "", "phone": None}
# ❌ 長く、繰り返し
if data["name"] is not None and data["name"] != "":
print("nameが存在する")
# ✅ Truthy/Falsyの活用
if data["name"]:
print("nameが存在する")
# 有効な値のみをフィルタリング
values = [0, "", None, "hello", [], [1, 2], False, 42]
valid = list(filter(None, values))
print(valid) # ["hello", [1, 2], 42]

filter(None, iterable)は、Falsyな値をすべて削除します。データの精製でよく使用されるパターンです。


まとめ

比較意味使用する場面
==値が同じか一般的な値の比較
is同じオブジェクトかNoneTrueFalseの比較
!=値が異なるか一般的な不一致の確認
is not異なるオブジェクトかis not None
python
# これらのパターンを覚えておきましょう
if x is None: # Noneのチェック
if x is not None: # Noneでないかチェック
if items: # 空でないか(Truthy)
if not items: # 空であるか(Falsy)


any()とall() — コレクションのTruthyの活用

python
scores = [85, 92, 0, 78, 95]
print(any(scores)) # True — 少なくとも1つTruthy(0ではないものがある)
print(all(scores)) # False — 0がFalsy
# 条件式とともに
print(any(s >= 90 for s in scores)) # True — 90以上があるか
print(all(s >= 60 for s in scores)) # False — すべて60以上か

any()all()は、内部的にTruthy/Falsyの判定を使用します。条件を簡潔に表現する場合に便利です。



短絡評価(Short-circuit)の活用

python
# or — 最初のTruthyを返す(ない場合は最後の値)
name = user_input or "デフォルト名"
# and — 最初のFalsyを返す(ない場合は最後の値)
result = data and data[0] # dataが空の場合は[]を返す、そうでない場合は最初の要素

orandは、ブール値を返すのではなく、Truthy/Falsyの判定を停止した時点の値を返します。デフォルト値の設定や、安全なアクセスパターンでよく使用されます。


==isの違いを理解しないと、見つけにくいバグが発生します。特に、Noneの比較では、==の代わりにisを使用する習慣は、Pythonコードの品質の基本です。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...