Convert True/False value read from file to boolean
Solution 1
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
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
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
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
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
Gabriel
Updated on April 29, 2021Comments
-
Gabriel about 3 years
I'm reading a
True - False
value from a file and I need to convert it to boolean. Currently it always converts it toTrue
even if the value is set toFalse
.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 valueTrue
orFalse
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 toTrue
? -
SethMMorton about 10 yearsYou could make it a "heroic"
ValueError
by doingraise ValueError("Cannot covert {} to a bool".format(s))
. -
Gabriel about 10 yearsSelecting this one since it uses no extra packages. Thanks guys!
-
SethMMorton about 10 yearsWhat's wrong with "extra packages"? Are you referring to
ast
? It's part of the standard library, so it's not really extra. -
Charlie Parker almost 8 yearsit might be a silly question but why does
bool
just not convert the stringsTrue
andFalse
to the boolean valuesTrue
andFalse
? Seems to be inconsistent behaviour from whatint
does. I just genuinely curious why my reasoning is wrong and why the other option was the decision. -
Charlie Parker almost 8 yearsit might be a silly question but why does
bool
just not convert the stringsTrue
andFalse
to the boolean valuesTrue
andFalse
? Seems to be inconsistent behaviour from whatint
does. I just genuinely curious why my reasoning is wrong and why the other option was the decision. -
Bill Kidd almost 8 yearsWhenever comparing strings I like to flatten the case, (where applicable). for example I would use: if s.upper() == 'TRUE': return True elif s.upper() == 'FALSE' return False
-
M07 over 7 years@samyi It is dangerous to use the eval method. stackoverflow.com/questions/1832940/…
-
Alex about 7 yearsEven better, do
bool(strtobool(my_string))
to cast the output as a boolean True / False variable -
Chris over 6 yearsast.literal_eval('false') throws an exception, which I think makes it less desirable
-
Ashwini Chaudhary over 6 years@Chris You can always wrap it around try-except in a custom function instead of using it directly then.
-
Nostalg.io about 6 yearsFYI. This is a terrible idea and you should never use
eval()
. In my opinion, it should be removed from the language. -
Keith Ripley about 6 yearsThis is VERY VERY BAD because it is a security flaw. If you use
eval()
on raw data from a file then it means that anyone with write access to that file can execute code at the same permissions level as your script. -
kev about 6 yearsAdditionally, if values have not the exact python spelling, e.g.
eval('false')
,eval('FALSE')
it will error. -
Ashwini Chaudhary over 4 years@HewwoCraziness It parses only expressions not any random code.
-
dericke about 4 years@AlexG crazy that a function called
strtobool()
does not, in fact, return abool
-
Ari over 3 yearsThis doesn't work unless the input value can actually be a boolean, otherwise, it seems to throw a value error. The only thing I can think of is to add a try/except to your function and on
ValueError
return false. -
Ben about 2 yearsThis gives a JSON Decode Error when the string is 'True' or 'False' i.e. title-format. Use json.loads('False'.lower) in that case.