tags:

views:

5835

answers:

9

Does anyone know how to do convert from a string to a boolean in Python? I found this link. But it doesn't look like a proper way to do it. I.e. using a built in functionality, etc.

EDIT: The reason I asked this is because I learned int("string"), from here. I tried bool ("string") but always got True.

+22  A: 

Really, you just compare the string to whatever you expect to accept as representing true, so you can do this:

s == 'True'

Or to checks against a whole bunch of values:

s in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh']

UPDATE: Ah! Try this on on the Python REPL:

>>> bool("foo")
True
>>> bool("")
False

Empty strings are false, everything else is true.

Keith Gaughan
+1: Not much could be simpler than `s == "True"`. But I've seen people make a real mess of this. def convert(s): if s == "True": return True; return False.
S.Lott
That's one of my pet hates! And it crops up all over the place.
Keith Gaughan
I prefer return s == "True" over the if/else
Dana
@Dana: everyone should. if x: return True is a terrible thing. The only thing worse is if x: return False.
S.Lott
if s == "True": return True elif s=="False": return False else: return raise
Unknown
It shows a lack of understanding of the boolean data type.
Ed Swangren
@Ed: What shows a lack of understanding?
Keith Gaughan
+1  A: 

you could always do something like

myString = "false"
val = (myString == "true")

the bit in parens would evaluate to False. This is just another way to do it without having to do an actual function call.

contagious
What is the `val = "false"` line doing on this example? Why is it there? What does it mean?
S.Lott
I think it means 42.
Geo
@Geo: I agree; but what was the question that is answered by that statement?
S.Lott
it was meant to be myString
contagious
+12  A: 
def str2bool(v):
  return v.lower() in ["yes", "true", "t", "1"]

Then call it like so:

str2bool("yes")

> True

str2bool("no")

> False

str2bool("stuff")

> False

str2bool("1")

> True

str2bool("0")

> False


Handling true and false explicitly:

You could also make your function explicitly check against a True list of words and a False list of words. Then if it is in neither list, you could throw an exception.

Brian R. Bondy
+1 elegant solution
wzzrd
+6  A: 

Starting with Python 2.6, there is now ast.literal_eval:

>>> import ast
>>> help(ast.literal_eval)
Help on function literal_eval in module ast:

literal_eval(node_or_string)
    Safely evaluate an expression node or a string containing a Python
    expression.  The string or node provided may only consist of the following
    Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
    and None.

Which seems to work, as long as you're sure your strings are going to be either "True" or "False":

>>> ast.literal_eval("True")
True
>>> ast.literal_eval("False")
False
>>> ast.literal_eval("F")
Traceback (most recent call last):
  File "", line 1, in 
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string
>>> ast.literal_eval("'False'")
'False'

I wouldn't normally recommend this, but it is completely built-in and could be the right thing depending on your requirements.

Jacob Gabrielson
Not sure of the general applicability of this solution, but it's very nice, in a general sort of way. +1!
TokenMacGuy
Yeah... this is a handy way to do it. Thanks!
Paul McMillan
+1  A: 

The usual rule for casting to a bool is that a few special literals (False, 0, 0.0, (), [], {}) are false and then everything else is true, so I recommend the following:

def boolify(val):
    if (
        type(val) is type('a string') or
        type(val) is type(u'a unicode')
        ):
        return not val in ('False', '0', '0.0')
    else:
        return bool(val)
DGGenuine
Your if statement can be simplified to `if isinstance(val, basestring):`
dbr
A: 

here's a hairy, built in way to get many of the same answers. Note that although python considers "" to be false and all other strings to be true, TCL has a very different idea about things.

>>> import Tkinter
>>> tk = Tkinter.Tk()
>>> var = Tkinter.BooleanVar(tk)
>>> var.set("false")
>>> var.get()
False
>>> var.set("1")
>>> var.get()
True
>>> var.set("[exec 'rm -r /']")
>>> var.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 324, in get
    return self._tk.getboolean(self._tk.globalgetvar(self._name))
_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']"
>>>

A good thing about this is that it is fairly forgiving about the values you can use. It's lazy about turning strings into values, and it's hygenic about what it accepts and rejects(notice that if the above statement were given at a tcl prompt, it would erase the users hard disk).

the bad thing is that it requires that Tkinter be available, which is usually, but not universally true, and more significantly, requires that a Tk instance be created, which is comparatively heavy.

What is considered true or false depends on the behavior of the Tcl_GetBoolean, which considers 0, false, no and off to be false and 1, true, yes and on to be true, case insensitive. Any other string, including the empty string, cause an exception.

TokenMacGuy
+1  A: 

You probably already have a solution but for others who are looking for a method to convert a value to a boolean value using "standard" false values including None, [], {}, and "" in addition to false, no , and 0.

def toBoolean( val ):
    """ 
    Get the boolean value of the provided input.

        If the value is a boolean return the value.
        Otherwise check to see if the value is in 
        ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]
        and returns True if value is not in the list
    """

    if val is True or val is False:
        return val

    falseItems = ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]

    return not str( val ).strip().lower() in falseItems
Chris McMillan
it's better to use sets, `not in` and your selection of false items is somewhat idiosyncratic.
SilentGhost
A: 
def str2bool(str):
  if isinstance(str, basestring) and str.lower() in ['0','false','no']:
    return False
  else:
    return bool(str)

idea: check if you want the string to be evaluated to False; otherwise bool() returns True for any non-empty string.

xvga
+1  A: 

Python already have a built-in function called eval

>>> eval("True")
True

>>> eval("False")
False
aatifh
eval is evil. Be very careful if your strings are from user entered data otherwise instead of "True" they might use it to do bad things.
StephenPaulger
If you know where the data comes from, there is no problem in using eval. I find this one very concise and it won't clutter my code with a util function.
Johan