Pythonで変数がnull(None)であるかを判定する場面は、データベースからの取得時や関数の戻り値など、さまざまな文脈で頻繁に発生します。このような空状態のチェックでよく使われるのがis演算子であり、意図しないエラーを防ぐ条件分岐を適切に構築できます。
この記事では、Pythonにおける空の値を正しく見分けるための基本的な使い方を順を追って解説していきます。他のプログラミング言語から移行した方が陥りやすい等価性と同一性の違いなど、サンプルコード付きで解説していきますので、ぜひ参考にしてください。
Pythonでnull(None)を判定する方法
Pythonには他の言語のnullに相当する値としてNoneという特殊なオブジェクトが存在します。Noneはメモリ上に常に一つだけ存在するシングルトンという性質を持っており、PythonのC APIドキュメントでも独自の型として解説されている仕様です。
null(None)の判定には、原則としてis演算子を使用します。==演算子は__eq__メソッドのオーバーライドに影響されるリスクがあるため、PEP 8「Programming Recommendations」でも「Noneとの比較には常にis/is notを使い、等価演算子を使ってはならない(never)」と明記されています。
判定に用いる代表的な手法は、以下の通りです。
- is演算子で同一性を判定する(推奨)
- ==演算子で等価性を判定する(PEP 8が強く非推奨とするスタイル)
- notを用いて暗黙的な偽(Falsyな値)をまとめて判定する
これらの演算子は一見すると似た結果を返しますが、内部的な比較の仕組みが大きく異なります。目的に応じて正しく使い分けることが、予期せぬエラーを防ぐための第一歩です。
is演算子で同一性を判定する
変数がNoneであるかを確かめる際は、is演算子を使うアプローチが推奨されています。これは二つのオブジェクトがメモリ上の同じ場所を指しているかを確認する手法であり、__eq__メソッドのオーバーライドに左右されず、常に同一オブジェクトかどうかを確認できる点が最大のメリットです。
is演算子を利用した基本的な使い方は、以下のコードの通りです。
value = None
if value is None:
print("変数はNoneです")
else:
print("変数には値が入っています")
上記のコードでは、変数valueがNoneという単一のオブジェクトと同一であるかを調べています。Pythonの公式ドキュメント(組み込み定数)でも、NoneはNoneTypeの唯一のインスタンスと説明されており、PEP 8ではNoneとの比較にis/is notを使うことが推奨されています。
is演算子は__eq__メソッドのオーバーライドに左右されないため、プログラムの予期せぬ挙動を防げます。そのため、特別な理由がない限りはこの書き方を採用してください。
==演算子で等価性を判定する
==演算子は値が等しいかどうかを調べるために使われ、オブジェクトの中身を比較する仕組みです。変数の状態の判定にも利用できますが、__eq__メソッドがオーバーライド(上書き)されているクラスの場合、意図せずTrueを返してしまうリスクがあります。
実際に==演算子で値を比較する使い方は、以下のコードの通りです。
value = None
if value == None:
print("値は等しいです")
上記のコードは動作しますが、PEP 8ではNoneとの比較に等価演算子を使ってはならない(never)と明記されており、linter(flake8等)ではE711警告が出るスタイルです。__eq__メソッドのオーバーライドによって、正しく状態を識別できないケースが生じます。
特にサードパーティ製のライブラリなどを扱う場面では、この演算子の仕様が原因でバグを引き起こしかねません。値の同値性ではなくオブジェクトの同一性を問う場面では、必ず前述のis演算子を活用しましょう。
notを用いて暗黙的な偽(Falsyな値)をまとめて判定する
変数がNoneだけではなく、空のリストや0などの偽として扱われる値もまとめて判定したい場合は、notを使用します。Pythonの条件式では、特定の値が暗黙的に偽(Falsyな値)として評価される仕様であり、Python公式ドキュメントの「真理値判定」ではNoneやFalse、数値の0、空文字列、空のリスト[]、空の辞書{}などが偽と定義されています。
Python公式は、真偽値変換の仕組みを次のように定義しています。
組み込み関数 bool() は、もしその値が真理値として解釈可能ならば、任意の値を真偽値に変換します (上記 真理値判定 節を参照してください)。
出典:Python公式ドキュメント 真理値判定
つまり、if文に直接渡した値は内部でbool()による真偽値変換が行われ、Noneや0、空文字列などが一律「偽」と扱われる仕様です。
暗黙的な偽を利用する判定の書き方は、以下の通りです。
value = ""
if not value:
print("値は偽として扱われます")
上記のコードでは、空文字列が偽(Falsyな値)として評価されるため、条件が満たされます。Noneが代入されていた場合も同様に処理が行われるのが特徴です。
ただし、0などの有効な値を誤ってスキップしてしまうリスクがあるため、実務では状況に合わせてis Noneによる厳密なチェックと使い分ける必要があります。
Pythonのif文でnullを判定する書き方
基本的な判定手法を踏まえたうえで、実務ではis Noneとis not Noneのどちらをどの場面で使うかを把握しておきたいところです。is Noneで値の不在を確認するケースだけではなく、is not Noneで値が存在する場合のみ後続処理を行うパターンや三項演算子を使ったコンパクトな書き方も実務で頻繁に登場します。
具体的なアプローチは、以下の通りです。
- is None / is not Noneで判定する
- 三項演算子を使ったコンパクトな書き方
それぞれの書き方と使い分けについて、順番に解説します。
is None / is not Noneで判定する
変数がNoneかどうかを判定する場合はif value is None:を、Noneではない場合に処理を進めたい場合はif value is not None:を使います。どちらも同一オブジェクトかどうかを確認する比較であるため、__eq__メソッドのオーバーライドに影響されない厳密な判定です。
is Noneとis not Noneの具体的な使い分けは、以下のコードの通りです。
value = None
# Noneであることを確認する
if value is None:
print("値はNoneです")
result = "hello"
# Noneではない場合のみ処理を進める
if result is not None:
print("結果が取得できました:", result)
上記のコードでは、is NoneでNoneの存在確認を行い、is not NoneでNoneではない場合の処理を記述しています。0や空文字列など、他の偽(Falsyな値)と区別して条件分岐を行いたい場合に最適な書き方です。
なお、not valueのような暗黙的な偽の判定は、0や空文字列もNoneと同様に偽と評価されるため、Noneのみを厳密にチェックしたい場面ではis Noneを使うことが推奨されます。
三項演算子を使ったコンパクトな書き方
Noneの判定とデフォルト値の設定を1行で記述したい場合は、三項演算子(条件式)を活用すると可読性が上がります。「値がNoneであればデフォルト値を、そうでなければ元の値を使う」というパターンは実務で頻繁に登場します。
三項演算子を用いたNone判定の書き方は、以下のコードの通りです。
value = None
# Noneの場合はデフォルト値を使う
result = "デフォルト値" if value is None else value
print(result) # デフォルト値
value2 = "実際の値"
result2 = "デフォルト値" if value2 is None else value2
print(result2) # 実際の値
上記のコードでは、is Noneを条件に三項演算子でデフォルト値のフォールバックを実現しています。if/elseブロックを展開せずに1行で表現できるため、関数の引数や辞書の値取得など、簡潔さが求められる場面に適しています。
なお、Python 3.8以降では代入式(ウォルラス演算子:=)を使ってNone判定と変数への代入を組み合わせることも可能ですが、可読性を損なわない範囲で活用することが前提です。
Pythonのnull判定に関するよくある質問
pandasの欠損値(NaN)はNoneと同じように判定できるか?
pandas Series/DataFrame内の欠損値(NaN)をis Noneで検出しようとしても、意図通りの結果にはなりません。NaNとNoneは型が異なる別のオブジェクトですが、pandasはNoneもNaN相当の欠損値として扱う仕組みです。
要素ごとの欠損状態をチェックする際は、pandasが提供するisna()メソッドを使うのが一般的です。pandas公式ドキュメントでは、isna()がNaNやNone、NaTをまとめて欠損値として検出できると説明されており、isnull()はisna()のエイリアスであるため、どちらを使っても同じ結果です。
正規表現の処理でNoneが返された場合はどう対処するか?
Python公式のreモジュールのre.match()やre.search()は、パターンが文字列にマッチしなかった場合にNoneを返す仕様です。Noneに対して直接.group()を呼び出すとAttributeErrorが発生するため、if match is not None:で戻り値を検証してからメソッドを呼び出す設計にしましょう。
※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。
ITやプログラミングに関するコラム
PythonをWebで実行する方法
共通テスト「情報Ⅰ」2年目で変わる、日本の教育と学び方
gitでブランチ(branch)を切り替える方法
git cloneでブランチを指定する方法
64GBのメモリが必要な人・不要な人の特徴
PCを再起動するコマンド一覧
CapsLock以外で大文字になる原因【Windows編】
パソコンで大文字になるのを解除する方法
面白いAIの活用事例を業界別に紹介
Gitでcommit(コミット)を取り消す方法
ITやプログラミングに関するニュース
株式会社HODL1がAI経営管理エージェントを提供開始、少人数での経営管理効率化を支援
株式会社サードスコープがKanataを発表、法人向けAI業務支援SaaSを展開
株式会社ナレッジセンスがChatSenseのPPTX出力機能を強化、資料修正負荷の軽減を支援
株式会社すららネットが「すらら」同時導入を公表、夜間中学で日本語学習と教科学習を支援
DUAL株式会社が空室通電DXと賃貸革命の連携を開始、空室時の通電管理効率化を推進
株式会社ITLINEがAWS生成AIシステム開発・運用を提供開始、企業管理型AI基盤の構築を支援
合同会社ウノマスがAI対応スコアを正式公開、LLMOとSEOの横断診断を支援
Markefan株式会社がmarke.aiを提供開始、BtoBマーケティングの属人化抑制を支援
株式会社FinatextがAIロールプレイング提供開始、金融機関の営業育成基盤構築を支援
株式会社アンドパッドがANDPAD ナレッジAIを提供開始、建設現場の情報検索と共有を支援
