CSVを読み込んだら値が NaN になっていた。計算結果がいつの間にか inf になっていた。関数を呼んだら戻り値が None だった——Pythonでデータを扱っていると、必ず出会うこの3つの特殊な値。😵
正体を知らずに放っておくと「== で比較したら反応しない」「if文の挙動が予想と違う」といったハマりポイントを生みます。逆に違いと判定方法を押さえれば、データの不整合やエッジケースに強い、ぐっとプロらしいコードが書けるようになります。✨
「コンピューターが数えられないなんてことあるの?」と思うかもしれませんが、Pythonの float(浮動小数点)型には扱える数値の範囲があります。
import sys
print(sys.float_info.max)
# 1.7976931348623157e+308
1.7976...×10^308——10の後ろに0が308個も続く、想像を絶する大きな数です。しかし、この値を超えるとPythonは「無限大(inf)」として扱うのです。🌀
最大値より大きな数を計算すると、自動的に無限大になります。
import sys
x = sys.float_info.max * 2
print(x) # inf
y = sys.float_info.max * -2
print(y) # -inf
もっと直感的に書くなら、float() に文字列で渡す方法があります。
positive_inf = float("inf")
negative_inf = float("-inf")
print(positive_inf) # inf
print(negative_inf) # -inf
どちらも型は float。「inf も実は数値の仲間」というのがポイントです。👍
import sys
big = sys.float_info.max
print(big + 1) # 1.7976931348623157e+308 ← 変わらない!
print(big * 2) # inf
「+1 しても変わらないのに ×2 したら inf になる」——これは桁落ちと呼ばれる現象で、あまりに大きい数値に対して小さい数(1)を足しても、相対的に小さすぎて無視されてしまうのです。⚠️
NaN(ナン)は Not a Number の略。「数値として扱うはずだったけど、数値として扱えなかったもの」を表す特殊な値です。たとえば、こんな計算で発生します。
x = float("inf") - float("inf")
print(x) # nan
「無限大から無限大を引いたら 0?」と思いきや、答えは NaN。数学的に定義できない計算結果がNaNとして返ってきます。🤯
明示的に NaN を作るには、こちらも float() を使います。
x = float("nan")
print(x) # nan
print(type(x)) # <class 'float'>
NaNには独特の性質があります。なんと、NaN同士を == で比較しても False が返ってくるのです。
x = float("nan")
print(x == float("nan")) # False ← 自分自身とすら等しくない!
「NaN なら True」と判定したくて x == float("nan") と書いてしまうと、永遠に True にならないバグを生みます。😱
import math
x = float("nan")
print(math.isnan(x)) # True
math モジュールは Python 標準なので、追加インストール不要。math.isnan() に変数を渡せば、NaN なら True、そうでなければ False が返ります。✅
import math
print(math.isinf(float("inf"))) # True
print(math.isinf(float("-inf"))) # True ← マイナス無限大もTrue
math.isinf() はプラス・マイナス両方の無限大で True を返します。プラス側だけ判定したいなら、x == float("inf") でOK(infは == で比較できます)。⚡
似ているようで違うのが None と NaN。
float)NoneType)def my_function():
print("hello")
# return 文がない
result = my_function()
print(result) # None
戻り値(return)を書いていない関数を呼び出すと、その戻り値は None になります。エラーにはなりません。
他にも、openpyxlでExcelの空のセルを読んだとき、辞書の存在しないキーを .get() で取得したときなど、「データがない」状況で頻繁に登場します。📋
Noneの判定では、== ではなく is を使うのがPython流儀です。
x = None
# 推奨
if x is None:
print("値がありません")
# 非推奨(動くけど避けるべき)
if x == None:
print("値がありません")
== は「同じ値か」を比較するのに対し、is は「同じオブジェクト(同じid)か」を比較します。Pythonでは None はプログラム全体でたった1つだけ存在するオブジェクトなので、is で確実に判定できます。🎯
x = None
y = None
print(id(x) == id(y)) # True ← 同じオブジェクト
NoneはPythonのif文で False と同じ扱いになります。しかし「Falseと同じ扱い」になる値は他にもたくさんあります。
NoneFalse00.0""[](){}set()注意:これらは「if文でFalseと同じ振る舞いをする」だけで、Falseそのものではありません。None == FalseはFalseです。明示的に「Noneかどうか」を判定したいときは必ずis Noneを使いましょう。📝
import math
def safe_divide(a, b):
if b is None:
return "bがNoneです"
if math.isnan(a) or math.isnan(b):
return "数値にNaNが含まれています"
if b == 0:
return float("inf")
return a / b
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # inf
print(safe_divide(10, None)) # bがNoneです
print(safe_divide(float("nan"), 2))# 数値にNaNが含まれています
こうした入力チェックを習慣にしておくと、データの欠損や異常値があってもプログラムが落ちなくなります。プロのコードと趣味のコードを分ける、地味だけど重要な差です。🛡️
NaN・inf・Noneの扱いは、データ分析・Web開発・自動化スクリプトなど、Pythonを使うあらゆる場面で出てきます。良書を1冊手元に置いておくと、エッジケース対応の引き出しが一気に増えます。
None や条件分岐の挙動など、Pythonの基本概念を体系的に学べる定番書。「なぜそう動くのか」が腹落ちします。
pandasやnumpyでは NaN は欠損値の標準表現。実データを扱う現場でNaNの取り扱いに迷わなくなる必読書。
None の判定に is を使うべき理由など、Pythonコミュニティの「お作法」を90項目に凝縮。中級者必読の一冊です。
オブジェクトのid、シングルトン、None の内部実装まで踏み込んで解説。「なぜ is None なのか」が完璧に理解できます。
エッジケース対応を書き続ける時間は地味にタイピング量が多い作業。打鍵感が良く、複数デバイス切替対応のキーボードがあると集中が長く続きます。
仕様です。IEEE 754という浮動小数点の国際規格で「NaN は自分自身を含むすべての値と等しくない」と定められており、Pythonもこれに従っています。判定するときは必ず math.isnan() を使いましょう。📜
False は明確に「偽」を表すブール値、None は「値が存在しない」を表すオブジェクトです。if文ではどちらも False 扱いになりますが、None == False は False。意味が違うので使い分けが必要です。⚖️
pandasのDataFrameでは .isna()・.isnull()・.dropna()・.fillna() といった専用メソッドが用意されています。NaNの存在チェックや埋め込みはこれらで行うのが基本です。📊
整数同士のゼロ除算は ZeroDivisionError でエラーになります。一方、numpyやpandasでのゼロ除算はインフ(inf)や NaN を返すケースが多いです。ライブラリによって挙動が違うので、ドキュメントで確認するのが安全です。⚠️
「値がない」を意図的に表現したいなら問題ありません。ただし、呼び出し側で None をチェックする責任が発生します。最近のPythonでは Optional[int] のような型ヒントで「None になりうる」ことを明示するのが推奨されています。✨
Pythonの NaN・inf・None は、最初は混乱しがちですが、それぞれの意味と判定方法を押さえれば、強力な道具になります。📐
math.isnan()math.isinf() または ==is Noneデータ分析、Web開発、自動化——どの分野でもこの3つはあなたの前に必ず現れます。「あれ、なぜ思った通りに動かない?」と感じたら、まずこの3つを疑ってみてください。今日学んだ引き出しを持っているだけで、デバッグ時間が劇的に短くなるはずです。🚀