1354

How do I convert a string into a boolean in Python? This attempt returns True:

>>> bool("False")
True
1
  • But when trying bool("string") it always returns True...except for the empty string bool("") Commented Mar 14, 2022 at 15:08

43 Answers 43

1413

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.lower() in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh']

Be cautious when using the following:

>>> bool("foo")
True
>>> bool("False") # beware!
True
>>> bool("")
False

Empty strings evaluate to False, but everything else evaluates to True. So this should not be used for any kind of parsing purposes.

Sign up to request clarification or add additional context in comments.

14 Comments

+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.
I prefer return s == "True" over the if/else
if s == "True": return True elif s=="False": return False else: return raise
Parsing strings to booleans is already implemented in distutils.util.strtobool: stackoverflow.com/a/18472142/923599
I know this is a REALLY old topic, but I wanted to attest that I have just spent 4 hours trying to debug my code. My mistake was trying to cast bool("False"). It will always cast to True.
|
567

Warning: This answer will no longer work as of Python 3.12 (it's deprecated as of 3.10)

Use:

bool(distutils.util.strtobool(some_string))

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.

Be aware that distutils.util.strtobool() returns integer representations and thus it needs to be wrapped with bool() to get Boolean values.

Given that distutils will no longer be part of the standard library, here is the code for distutils.util.strtobool() (see the source code for 3.11.2).

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,))

12 Comments

That function is tantalizing. It would be perfect if it handled integers and None and str(None) as input.
I much prefer this to the higher voted answers... it's from stdlib and does exactly what's required. There is generally no reason to need an actual bool instead of 1/0 as long as you're not doing bad stuff like if x == False... and if you're dealing with ints and Nones you don't need a special function, you can just check them directly if myint: or if not maybe_none_var:
@Secator bool is a sub-class of int
To save someone some Googling of errors: import distutils and import distutils.util for this to work.
Be aware, that the distutils package is deprecated since python 3.10 and will be removed in version 3.12.
|
374
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.

3 Comments

little enhancement can be made using, str(v).lower() instead of v.lower(). Then, it can work even it is not string, e.g. 1, 0
RE: handling true/false explicitly, you could also provide a default value if the string isn't matched, much like how true/false command-line prompts work: Continue? (y/N)
Prolly add "y" if you're going to include "t"...
205

The JSON parser is also useful for in general converting strings to reasonable python types.

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True

3 Comments

Be careful though, no validation are done that the return type is a boolean. json.loads("[42]".lower()) -> [42]
why is .lower() needed? When I don't use it, for example x = "False" j = json.loads(x), I get the error json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
@AmbassadorKosh because JSON only recognizes literal true and false values; see json-schema.org/understanding-json-schema/reference/…
135

Since Python 2.6 you can use ast.literal_eval, and it's still available in Python 3.

Evaluate an expression node or a string containing only a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis.

This can be used for evaluating strings containing Python values without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.

This function had been documented as “safe” in the past without defining what that meant. That was misleading. This is specifically designed not to execute Python code, unlike the more general eval(). There is no namespace, no name lookups, or ability to call out. But it is not free from attack: A relatively small input can lead to memory exhaustion or to C stack exhaustion, crashing the process. There is also the possibility for excessive CPU consumption denial of service on some inputs. Calling it on untrusted data is thus not recommended.

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 "<stdin>", line 1, in <module>
  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.

6 Comments

Not sure of the general applicability of this solution, but it's very nice, in a general sort of way. +1!
Gaah, that's horrifying! Then again, you did say you don't recommend it, and it does answer the question neatly. Good find!
Unfortunately it doesn't handle this case >>>ast.literal_eval('true') or ast.literal_eval('TRUE') Raises >>> raise ValueError('malformed string') The fix is simple though ast.literal_eval(to_test.title())
Not a great solution to this particular question, but... Wow, literal_eval is damn useful! String to list, dict, ect.
Does it work on unicodes to? In my Django view I have an incoming value which I want to change to boolean, it is giving a malformed string exception.
|
84

WARNING: Do not use the following code unless you actually know what you are doing with it. Please read the attached disclaimers and make sure you trust your inputs as using this on untrusted inputs could destroy your data and/or cost you your job.

If you know the string will be either "True" or "False", you could just use eval(s).

>>> eval("True")
True
>>> eval("False")
False

Only use this if you are sure of the contents of the string though, as it will throw an exception if the string does not contain valid Python, and will also execute code contained in the string.

8 Comments

that string will come from somewhere. if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
@nurettin, hence my comment about only using it if you're sure of the contents of the string.
please please please, there are a LOT safer options above, why would you want to use eval for a simple string comparison you can never be 100% certain that a piece of code is going to stay the same and behave the same over time but there's a slight chance that you leave the eval in there then the disaster soup is ready
This is the correct answer I was googling for. eval("True") = True and eval("False") = False. Simple. I use it to ping a config file for booleans.
Part of me says capital letter "WARNING" is in order. On the other hand the other part says if someone is dumb enough to copy-paste the answer without thinking what it really does, they kinda deserved to be hacked
|
45

There is an elegant solution with pydantic:

For pydantic >=2:

from pydantic import TypeAdapter
    
>>> TypeAdapter(bool).validate_python("true")
True

>>> TypeAdapter(bool).validate_python("off")
False

For pydantic <2:

import pydantic
    
>>> pydantic.parse_obj_as(bool, "true")
True

>>> pydantic.parse_obj_as(bool, "off")
False

Comments

31

NOTE: DON'T EVER USE eval() if it takes an input directly or indirectly from the user because it is highly subject to abuse:

eval('os.system(‘rm -rf /’)')

But cheers! Study finds also that eval() is not evil and it is perfectly OK for TRUSTED CODE. You can use it to convert a boolean string such as "False" and "True" to a boolean type.


I would like to share my simple solution: use the eval(). It will convert the string True and False to proper boolean type IF the string is exactly in title format True or False always first letter capital or else the function will raise an error.

e.g.

>>> eval('False')
False

>>> eval('True')
True

Of course for dynamic variable you can simple use the .title() to format the boolean string.

>>> x = 'true'
>>> eval(x.title())
True

This will throw an error.

>>> eval('true')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'true' is not defined

>>> eval('false')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'false' is not defined

4 Comments

wow, for anyone finding this: do NOT use this for anything else than simple scripts. If you use this in any serious application you will open yourself up to all kinds of unwanted code execution. Imagine a scenario where you parse input from a user and to convert a string to a boolean you use this. In this scenario an attacker can basically do anything that your code does. Don't trust me? Try this: import os eval("os.getcwd()")
@MartinBraun Ah yes study finds that you can execute this eval('os.system(‘rm -rf /’)') and it deletes all the files in that directory. However eval() are perfectly OK for a trusted code it is not really evil. So I better put a note to be careful.
How about literal_eval?
@MartinBraun yes, to your first line, and I've found that there's no such thing as a, "simple script." All code eventually becomes production code (or may, but there's no guessing). So what you said but I'd stop after the word, "this," and for all the reasons you cite.
24

This version keeps the semantics of constructors like int(value) and provides an easy way to define acceptable string values.

valid = {'true': True, 't': True, '1': True,
         'false': False, 'f': False, '0': False,
         }

def to_bool(value):
    """Convert string value to boolean."""

    if isinstance(value, bool):
        return value

    if not isinstance(value, basestring):
        raise ValueError('invalid literal for boolean. Not a string.')

    lower_value = value.lower()
    if lower_value in valid:
        return valid[lower_value]
    else:
        raise ValueError('invalid literal for boolean: "%s"' % value)


# Test cases
assert to_bool('true'), '"true" is True' 
assert to_bool('True'), '"True" is True' 
assert to_bool('TRue'), '"TRue" is True' 
assert to_bool('TRUE'), '"TRUE" is True' 
assert to_bool('T'), '"T" is True' 
assert to_bool('t'), '"t" is True' 
assert to_bool('1'), '"1" is True' 
assert to_bool(True), 'True is True' 
assert to_bool(u'true'), 'unicode "true" is True'

assert to_bool('false') is False, '"false" is False' 
assert to_bool('False') is False, '"False" is False' 
assert to_bool('FAlse') is False, '"FAlse" is False' 
assert to_bool('FALSE') is False, '"FALSE" is False' 
assert to_bool('F') is False, '"F" is False' 
assert to_bool('f') is False, '"f" is False' 
assert to_bool('0') is False, '"0" is False' 
assert to_bool(False) is False, 'False is False'
assert to_bool(u'false') is False, 'unicode "false" is False'

# Expect ValueError to be raised for invalid parameter...
try:
    to_bool('')
    to_bool(12)
    to_bool([])
    to_bool('yes')
    to_bool('FOObar')
except ValueError, e:
    pass

2 Comments

Nit: Your last "test case" will error out on the first call and not test the others. Also, it will not fail if an error is not raised.
The definition of valid should be placed outside the function, or the dict will be rebuilt on every call, removing the majority of the performance benefit of using a dict in the first place.
17

you could always do something like

my_string = "false"
val = (my_string == "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.

2 Comments

What is the val = "false" line doing on this example? Why is it there? What does it mean?
this exactly what I was looking for, evaluating an input field from a file and based on the outcome storing a boolean. thank you.
15

Here's is my version. It checks against both positive and negative values lists, raising an exception for unknown values. And it does not receive a string, but any type should do.

def to_bool(value):
    """
       Converts 'something' to boolean. Raises exception for invalid formats
           Possible True  values: 1, True, "1", "TRue", "yes", "y", "t"
           Possible False values: 0, False, None, [], {}, "", "0", "faLse", "no", "n", "f", 0.0, ...
    """
    if str(value).lower() in ("yes", "y", "true",  "t", "1"): return True
    if str(value).lower() in ("no",  "n", "false", "f", "0", "0.0", "", "none", "[]", "{}"): return False
    raise Exception('Invalid value for boolean conversion: ' + str(value))

Sample runs:

>>> to_bool(True)
True
>>> to_bool("tRUe")
True
>>> to_bool("1")
True
>>> to_bool(1)
True
>>> to_bool(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: 2
>>> to_bool([])
False
>>> to_bool({})
False
>>> to_bool(None)
False
>>> to_bool("Wasssaaaaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: Wasssaaaaa
>>>

6 Comments

One could get bitten by this: to_bool(["hello"]) which should be a perfectly valid call, if [] is supported
Returns "Exception: Invalid value for boolean conversion: ['hello']", which is expected and documented. In my opinion an empty list was clearly a false, but ['false'] wasn't clearly anything, so I left it out intentionally - that's a feature not a bug. Should be easy to add support for returning true for non-empty lists if that's what you want.
shure you documented it. But in real live one would never call to_bool([]). Instead he would do something along these lines: myList=someFunctionThatReturnAList `if (is_bool(myList)):...´ so one have a list and want to know if this list is None or empty.
Why not try this: >>> def a2b(arg): ... default = bool(arg) ... if isinstance(arg, str): ... return arg.lower() in ['true', 't', 'yes', 'y', '1'] ... else: ... return default
Minor point: you should probably prefer ValueError over a plain Exception.
|
13

A cool, simple trick (based on what @Alan Marchiori posted), but using yaml:

import yaml

parsed = yaml.load("true")
print bool(parsed)

If this is too wide, it can be refined by testing the type result. If the yaml-returned type is a str, then it can't be cast to any other type (that I can think of anyway), so you could handle that separately, or just let it be true.

I won't make any guesses at speed, but since I am working with yaml data under Qt gui anyway, this has a nice symmetry.

3 Comments

The yaml module is a third party library: PyYAML
for more security against untrusted input yaml.safe_load instead of yaml.load
This one is nice because it will also handle on and off
10

A dict (really, a defaultdict) gives you a pretty easy way to do this trick:

from collections import defaultdict
bool_mapping = defaultdict(bool) # Will give you False for non-found values
for val in ['True', 'yes', ...]:
    bool_mapping[val] = True

print(bool_mapping['True']) # True
print(bool_mapping['kitten']) # False

If you only want to map known values and throw an exception otherwise:

truthy_strings = ['True', 'yes']  # ... and so on
falsy_strings = ['False', 'no']   # ... and so on

bool_mapping = {}
for v in truthy_strings:
    bool_mapping[v] = True
for v in falsy_strings:
    bool_mapping[v] = False

If you want to be too clever by half, you can shorten this with itertools

from itertools import chain, repeat

bool_mapping = dict(chain(zip(truthy_strings, repeat(True)), zip(falsy_strings, repeat(False))))

This is probably dumb but itertools tricks are vaguely amusing.

Comments

10

I don't agree with any solution here, as they are too permissive. This is not normally what you want when parsing a string.

So here the solution I'm using:

def to_bool(bool_str):
    """Parse the string and return the boolean value encoded or raise an exception"""
    # replace basestring by str in python 3.x
    if isinstance(bool_str, basestring) and bool_str: 
        if bool_str.lower() in ['true', 't', '1']: return True
        elif bool_str.lower() in ['false', 'f', '0']: return False
        
    #if here we couldn't parse it
    raise ValueError("%s is no recognized as a boolean value" % bool_str)

And the results:

>>> [to_bool(v) for v in ['true','t','1','F','FALSE','0']]
[True, True, True, False, False, False]
>>> to_bool("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in to_bool
ValueError: '' is no recognized as a boolean value

Just to be clear because it looks as if my answer offended somebody somehow:

The point is that you don't want to test for only one value and assume the other. I don't think you always want to map Absolutely everything to the non parsed value. That produces error prone code.

So, if you know what you want code it in.

10 Comments

I think you're missing the point: the point of the answers was to demonstrate the general principle, not to tell person who asked the question exactly how they should do it. The person who asked the question originally was overthinking what's actually a simple problem.
@Keith I disagree. The point is answering the question as it is asked.
The question asked was how to convert a string to a boolean. That was the question I answered. I have no idea what's considered a valid boolean string for the original poster, and nor do you. That's why it's more important to demonstrate the general principle than give the poster the full answer. The original poster didn't need everything spelled out to them: all they needed was for the general principle to be demonstrated. From that, anybody competent will get to your answer.
@Keith not sure what this is all about but the point is building knowledge. I'm not "judging" your answer, I fell no other answer was "complete" as they missed the fact that parsing a boolean has 3 outcomes, true, false or unparsable. That's all. (I will just pretend I never read the last line of your comment)
@dshepherd the isinstance is there to be sure I'm parsing what I expect. I'm parsing strings so a method car_race.lower() that by chance returns '1' shouldn't return true, it should throw a ValueError. But it might suffice in other cases.
|
9

By using below simple logic you can convert a string say a = 'true' or 'false', to boolean.

a = a.lower() == 'true'

if a == 'true' then this will set a=True and if a == 'false' then a=False.

3 Comments

and what if a = '0' ?
@sagi -Then we can use: a = (str(a).lower() == 'true') | (str(a).lower() == '1')
But this also converts "truee"to true. generally we want an exception if the input is invalid
8

After having seen so many home brewn solutions, why not use something existing? All you need is:

from attrs.converters import to_bool

From the docs:

Convert "boolean" strings (e.g., from env. vars.) to real booleans

It does what you want: convert the strings True, true, yes, on, 1 (and some more) to True and False, false etc... to False.

It also raises an error if the string does not represent something which can be interpreted as boolean.

attrs is available from pypi.

1 Comment

This is the most realistic Pythonic way to do this. Django, etc. are fine too except that's a heavy dep if you're not already using it. Rolling your own is absolutely not the way to do it.
6

Yet another option

from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True

Comments

6

I use

# function
def to_bool(x):
    return x in ("True", "true", True)

# test cases
[[x, to_bool(x)] for x in [True, "True", "true", False, "False", "false", None, 1, 0, -1, 123]]
"""
Result:
[[True, True],
 ['True', True],
 ['true', True],
 [False, False],
 ['False', False],
 ['false', False],
 [None, False],
 [1, True],
 [0, False],
 [-1, False],
 [123, False]]
"""

Comments

5

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

1 Comment

it's better to use sets, not in and your selection of false items is somewhat idiosyncratic.
5

If you have control over the entity that's returning true/false, one option is to have it return 1/0 instead of true/false, then:

boolean_response = bool(int(response))

The extra cast to int handles responses from a network, which are always string.

Update 2021: "which are always string" -- this is a naive observation. It depends on the serialization protocol used by the library. Default serialization of high-level libraries (the ones used by most web devs) is typically to convert to string before being serialized to bytes. And then on the other side, it's deserialized from bytes to string, so you've lost any type information.

Comments

5

If you like me just need boolean from variable which is string. You can use distils as mentioned by @jzwiener. However I could not import and use the module as he suggested.

Instead I end up using it this way on python3.7

distutils string to bool in python

from distutils import util # to handle str to bool conversion
enable_deletion = 'False'
enable_deletion = bool(util.strtobool(enable_deletion))

distutils is part of the python std lib, so no need to install anything, which is great! 👍

2 Comments

Be aware, that the distutils package is deprecated since python 3.10 and will be removed in version 3.12.
Like everything else in life, good things come to an end :(
5

If you know that your input will be either "True" or something else, then why not use:

def bool_convert(s):
    return s == "True"

2 Comments

You actually don't need the if s else False bit. Think about how "False" == "True" will already return False.
If you are unsure if the input s is a string or already a boolean, you can add if type(s) is bool: return s.
4

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 (isinstance(val, basestring) and bool(val)):
        return not val in ('False', '0', '0.0')
    else:
        return bool(val)

Comments

4

You can also evaluate any string literal :

import ast
ast.literal_eval('True')  # True
type(ast.literal_eval('True'))  # <class 'bool'>


ls = '[1, 2, 3]'
ast.literal_eval(ls)  # [1, 2, 3]
type(ast.literal_eval(ls))  # <class 'list'>

Comments

3

This is the version I wrote. Combines several of the other solutions into one.

def to_bool(value):
    """
    Converts 'something' to boolean. Raises exception if it gets a string it doesn't handle.
    Case is ignored for strings. These string values are handled:
      True: 'True', "1", "TRue", "yes", "y", "t"
      False: "", "0", "faLse", "no", "n", "f"
    Non-string values are passed to bool.
    """
    if type(value) == type(''):
        if value.lower() in ("yes", "y", "true",  "t", "1"):
            return True
        if value.lower() in ("no",  "n", "false", "f", "0", ""):
            return False
        raise Exception('Invalid value for boolean conversion: ' + value)
    return bool(value)

If it gets a string it expects specific values, otherwise raises an Exception. If it doesn't get a string, just lets the bool constructor figure it out. Tested these cases:

test_cases = [
    ('true', True),
    ('t', True),
    ('yes', True),
    ('y', True),
    ('1', True),
    ('false', False),
    ('f', False),
    ('no', False),
    ('n', False),
    ('0', False),
    ('', False),
    (1, True),
    (0, False),
    (1.0, True),
    (0.0, False),
    ([], False),
    ({}, False),
    ((), False),
    ([1], True),
    ({1:2}, True),
    ((1,), True),
    (None, False),
    (object(), True),
    ]

1 Comment

Use str instead of type('')
3

I completely agree with the solution of @Jacob\ Gabrielson but the thing is ast.literal_eval only work with string value of True and False not with true or false. So you just have to use .title() for it to work

import ast
ast.literal_eval("false".title())
# or
ast.literal_eval("False".title())

2 Comments

does not solve the problem that the string might be "0". >>> type(ast.literal_eval("0".title())) <class 'int'>
thank youu, no third party packages, and works nicely with strings
3

In python version 3.10 you could do something like this;

def stringToBool(string: str) -> bool:
    match(string.lower()):
        case 'true':
            return True
        case 'false':
            return False

The match-statement is equivalent to switch in C++.

Comments

2

Use this solution:

def to_bool(value) -> bool:
    if value == 'true':
        return True
    elif value == 'True':
        return True
    elif value == 'false':
        return False
    elif value == 'False':
        return False
    elif value == 0:
        return False
    elif value == 1:
        return True
    else:
        raise ValueError("Value was not recognized as a valid Boolean.")

1 Comment

I like this, because its one of the only solutions dealing with incorrect input properly
2

simple solution is

RUN_LOCAL = True if os.environ.get("RUN_LOCAL") == "True" else False

In this case if RUN_LOCAL variable is "True" it will be converted to boolean True in RUN_LOCAL variable else it will be False. You can add additional verifications if you are planning to input other strings like low case true and false and so on but the idea is simple and works without a need of creating new functions

2 Comments

It can be shortened to just os.environ.get("RUN_LOCAL") == "True"
if you don't need the False option when you are right , but if you want to verify that it has only True or False then my example is needed.
2

If you want to be able to customize it, while having appropriate defaults for it:

def tobool(val, truthy=["true", "1", "on", "y", "yes", "t", "i"], falsy=["false", "0", "off", "n", "no", "f", "o"], strfunc = (lambda x: str(x).lower())):
    ch = strfunc(val)
    if ch in truthy:
        return True
    elif ch in falsy:
        return False
    else:
        return None

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.