Convert True/False value read from file to boolean
PythonStringBooleanPython Problem Overview
I'm reading a True - False
value from a file and I need to convert it to boolean. Currently it always converts it to True
even if the value is set to False
.
Here's a MWE
of what I'm trying to do:
with open('file.dat', mode="r") as f:
for line in f:
reader = line.split()
# Convert to boolean <-- Not working?
flag = bool(reader[0])
if flag:
print 'flag == True'
else:
print 'flag == False'
The file.dat
file basically consists of a single string with the value True
or False
written inside. The arrangement looks very convoluted because this is a minimal example from a much larger code and this is how I read parameters into it.
Why is flag
always converting to True
?
Python Solutions
Solution 1 - Python
bool('True')
and bool('False')
always return True
because strings 'True' and 'False' are not empty.
To quote a great man (and Python documentation):
> ### 5.1. Truth Value Testing
>
> Any object can be tested for truth value, for use in an if or while
> condition or as operand of the Boolean operations below. The
> following values are considered false:
>
> * …
> * zero of any numeric type, for example, 0
, 0L
, 0.0
, 0j
.
> * any empty sequence, for example, ''
, ()
, []
.
> * …
>
> All other values are considered true — so objects of many types
> are always true.
The built-in bool
function uses the standard truth testing procedure. That's why you're always getting True
.
To convert a string to boolean you need to do something like this:
def str_to_bool(s):
if s == 'True':
return True
elif s == 'False':
return False
else:
raise ValueError # evil ValueError that doesn't tell you what the wrong value was
Solution 2 - Python
you can use distutils.util.strtobool
>>> from distutils.util import strtobool
>>> strtobool('True')
1
>>> strtobool('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.
Solution 3 - Python
Use ast.literal_eval
:
>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False
> Why is flag always converting to True?
Non-empty strings are always True in Python.
Related: Truth Value Testing
If NumPy is an option, then:
>>> import StringIO
>>> import numpy as np
>>> s = 'True - False - True'
>>> c = StringIO.StringIO(s)
>>> np.genfromtxt(c, delimiter='-', autostrip=True, dtype=None) #or dtype=bool
array([ True, False, True], dtype=bool)
Solution 4 - Python
The cleanest solution that I've seen is:
from distutils.util import strtobool
def string_to_bool(string):
return bool(strtobool(str(string)))
Sure, it requires an import, but it has proper error handling and requires very little code to be written (and tested).
Solution 5 - Python
I'm not suggested this as the best answer, just an alternative but you can also do something like:
flag = reader[0] == "True"
flag will be True
id reader[0] is "True", otherwise it will be False
.
Solution 6 - Python
Currently, it is evaluating to True
because the variable has a value. There is a good example found here of what happens when you evaluate arbitrary types as a boolean.
In short, what you want to do is isolate the 'True'
or 'False'
string and run eval
on it.
>>> eval('True')
True
>>> eval('False')
False
Solution 7 - Python
If you want to be case-insensitive, you can just do:
b = True if bool_str.lower() == 'true' else False
Example usage:
>>> bool_str = 'False'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
False
>>> bool_str = 'true'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
True
Solution 8 - Python
You can use dict to convert string to boolean. Change this line flag = bool(reader[0])
to:
flag = {'True': True, 'False': False}.get(reader[0], False) # default is False
Solution 9 - Python
str2bool
pip install>>> from str2bool import str2bool
>>> str2bool('Yes')
True
>>> str2bool('FaLsE')
False
Solution 10 - Python
You can do with json
.
In [124]: import json
In [125]: json.loads('false')
Out[125]: False
In [126]: json.loads('true')
Out[126]: True
Solution 11 - Python
Just to add that if your truth value can vary, for instance if it is an input from different programming languages or from different types, a more robust method would be:
flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support
And a more performant variant would be (set lookup is O(1)):
TRUTHS = set(['True','true',1,'T','t','1'])
flag = value in truths
Solution 12 - Python
If your data is from json, you can do that
> import json > > json.loads('true') > > True
Solution 13 - Python
If you need quick way to convert strings into bools (that functions with most strings) try.
def conv2bool(arg):
try:
res= (arg[0].upper()) == "T"
except Exception,e:
res= False
return res # or do some more processing with arg if res is false
Solution 14 - Python
Using dicts to convert "True" in True:
def str_to_bool(s: str):
status = {"True": True,
"False": False}
try:
return status[s]
except KeyError as e:
#logging
Solution 15 - Python
If you have
>>> my_value = "False"
then either do
>>> my_value in "False"
True
>>> my_value in "True"
False
or
>>> "False" in my_value
True
>>> "True" in my_value
False