◀ 21.

Pythonにおける変数が空かどうか判定する方法

▶
この記事の要点
  • 基本は if not val:。空文字・空リスト・空辞書・None・0 のどれでも「空」と判定される
  • None だけを判定したいなら if val is None:(== None ではなく is を使う)
  • 0 や False を「値あり」として扱いたい場面では not val を使わない
  • 空白だけの文字列は not val.strip()、NumPy 配列は arr.size == 0、pandas は df.empty
  • そもそも変数が未定義なら NameError。先に None などで初期化しておく

結論: if not で判定する

Python では、空の値は if 文の条件で「偽」として扱われます。そのため、変数が空かどうかは次のように書くのが最も簡潔で、Python の公式スタイルガイド(PEP 8)でも推奨されている書き方です。

if not val1:
    # val1 が空の場合の処理
    print('空です')
else:
    print('値があります')

文字列でもリストでも辞書でも同じ書き方で判定できます。len(val1) == 0 や val1 == [] と書いても動きますが、型ごとに書き分ける必要があるため、通常は not を使います。

仕組み: 偽として扱われる値(falsy)

if の条件に置いた値は、真か偽かに自動で変換されて判定されます。偽として扱われる主な値は次のとおりで、これ以外のほとんどの値は真になります。

種類偽になる値真になる例
NoneNone―
真偽値FalseTrue
数値0、0.01、-1、0.1
文字列''(空文字)' '(空白 1 つ)、'0'、'False'
リスト・タプル[]、()[None]、[0]
辞書・集合{}、set(){'a': None}

文字列の '0' や 'False' は中身があるので真です。また、要素が None だけのリスト [None] も「要素が 1 つある」ので真になります。

目的別の判定方法

判定したいこと書き方
空っぽ全般(None・空文字・空リスト・0 など)if not val:
None かどうかだけif val is None:
None でも空文字でもない文字列if val:(文字列型が確実な場合)
空白だけの文字列も空とみなすif not val or not val.strip():
空文字だけif val == '':
リストの要素数が 0if not lst: または if len(lst) == 0:
辞書にキーがないif 'key' not in d:

落とし穴

0 や False も「空」と判定される

数値を扱う変数で not を使うと、正当な値の 0 まで「未入力」と判定されてしまいます。「値が設定されていない」を None で表しているなら、is None で判定します。

stock = 0  # 在庫 0 個という正しいデータ

if not stock:
    print('在庫情報なし')   # 0 でもここに入ってしまう

if stock is None:
    print('在庫情報なし')   # 0 のときは入らない

None の判定に == を使わない

val == None でもたいていは動きますが、クラスが == の動作を独自に定義していると結果が変わる可能性があります。None は常に 1 つしか存在しないオブジェクトなので、同一性を調べる is / is not で比較するのが正しい書き方です。

NumPy 配列や pandas では not が使えない

NumPy の配列に if not arr: と書くと、要素が 2 つ以上ある場合に ValueError: The truth value of an array with more than one element is ambiguous になります。要素数で判定します。

import numpy as np
import pandas as pd

arr = np.array([])
if arr.size == 0:
    print('配列が空')

df = pd.DataFrame()
if df.empty:
    print('DataFrame が空')

未定義の変数は判定できない

一度も代入していない変数を if not val: で調べると、空かどうか以前に NameError になります。条件によって代入されない可能性がある変数は、先頭で val = None のように初期化しておきます。辞書の値なら d.get('key') を使えば、キーがないときに None が返ります。

よくある使い方: 引数の省略を None で判定する

関数の引数が渡されなかったことを判定する場面では、既定値を None にして is None で調べるのが定番です。既定値に [] や {} を直接書くと、そのオブジェクトが呼び出しの間で共有されてしまい、前回の呼び出しで追加した要素が残るという有名な落とし穴があります。

# NG: 既定値のリストが呼び出しをまたいで共有される
def add_tag(tag, tags=[]):
    tags.append(tag)
    return tags

# OK: None で「省略された」を表し、関数の中で新しく作る
def add_tag(tag, tags=None):
    if tags is None:
        tags = []
    tags.append(tag)
    return tags

ここで if not tags: と書くと、呼び出し側が意図的に渡した空リストまで新しいリストに置き換わってしまいます。「省略された」と「空が渡された」を区別したいときは is None を使い分けます。

確認方法

ある値が真と偽のどちらに扱われるか迷ったら、bool() で確認できます。

>>> bool('')
False
>>> bool(' ')
True
>>> bool([0])
True
>>> bool(0.0)
False

関連

Post Share
子ページ

子ページはありません

同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 型
  5. 標準ライブラリ
  6. 外部ライブラリ
  7. 制御構文
  8. リスト(配列)
  9. タプル
  10. セット
  11. 辞書(dict)
  12. クラスとメソッド
  13. 継承の概念と必要性
  14. 継承の構文
  15. コンストラクタ
  16. cookieの値の設定と取得
  17. 例外処理
  18. 例外を文字列で出力する方法
  19. httpリクエスト(curl)をする方法
  20. Responseオブジェクトの中身の確認
  21. 変数が空かどうか判定する方法
  22. タイムゾーンの設定と現在日時の取得と文字列化
  23. シングルクォーテーションとダブルクォーテーションの違い