Background
str = "True" と文字列になっている値をBoolにしたい場合があります。 直感的にbool(str) にしたいのですが思った結果が出ません。ここでは、TrueやFalseなどの文字列からBool型にする方法を紹介します。
組み込み関数 bool
組み込み関数として bool が存在します。 "True" となっているものは True(bool)に、 "False" となっているものは False(bool)に変換しそうですが実際は違います。 なぜなら、bool関数は入力値が空文字以外はTrueと出力され、空文字の場合はFalseと出力されます。そのため、bool("False")としても空文字以外と判定されてしまうためTrueと出力されます。
>>> str_true = "True"
>>> str_false = "False"
>>> bool(str_true)
True
>>> bool(str_false)
True
Method
解決方法として distutils.util パッケージ内の strtobool関数を使います。
公式のドキュメントを見ると、
真偽値をあらわす文字列を真(1)または偽(0)に変換します。
真の値は y, yes, t, true, on そして 1 です。偽の値は n, no, f, false, off そして 0 です。 val が上のどれでもない時は ValueError を起こします。
と書いてあります。
Pythonでは Trueは 1、 Falseは0と同義なのでstrtoboolをそのまま使って問題ないです。
Development
>>> from distutils.util import strtobool
>>> str_true = "True"
>>> str_false = "False"
>>> strtobool(str_true)
1
>>> strtobool(str_false)
0
# 数字だと不安に思う人はbool関数でラッピングする
>>> bool(strtobool(str_true))
True
>>> bool(strtobool(str_false))
False
びっくりすることに、上記でチラッと書いた通り、yes/noやon/offもTrue/False(bool)に変換してくれます。
>>> str_yes = "Yes"
>>> str_no = "No"
>>> str_on = "On"
>>> str_off = "Off"
>>> bool(strtobool(str_yes))
True
>>> bool(strtobool(str_no))
False
>>> bool(strtobool(str_on))
True
>>> bool(strtobool(str_off))
False
Supplement
開発するひとによってはTRUE True trueといろんな書き方のパターンがあります。どれでも対応できるのか確認すると、strtobool内で引数にlowerを使って小文字に変換しています。なのでどれでもOKです。
def strtobool (val):
"""Convert a string representation of truth to true (1) or false (0).
True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if
'val' is anything else.
"""
val = val.lower()
if val in ('y', 'yes', 't', 'true', 'on', '1'):
return 1
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))