在Python中从字符串转换为布尔值

如何在Python中将字符串转换为布尔值?这个尝试返回True:

>>> bool("False")True
1094003 次浏览

实际上,你只是将字符串与你期望接受的表示true的字符串进行比较,所以你可以这样做:

s == 'True'

或者检查一大堆值:

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

使用以下物品时请谨慎:

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

空字符串的值为False,但其他所有内容的值为True。所以这个不应该用于任何解析目的。

你可以这样做

my_string = "false"val = (my_string == "true")

parens中的位将计算为False。这是另一种不需要进行实际函数调用的方法。

def str2bool(v):return v.lower() in ("yes", "true", "t", "1")

然后像这样称呼它:

>>> str2bool("yes")True>>> str2bool("no")False>>> str2bool("stuff")False>>> str2bool("1")True>>> str2bool("0")False

显式处理true和false:

您还可以使函数显式地检查True单词列表和False单词列表。然后,如果它不在两个列表中,则可以抛出异常。

从Python 2.6开始,你可以使用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 Pythonexpression.  The string or node provided may only consist of the followingPython literal structures: strings, numbers, tuples, lists, dicts, booleans,and None.

这似乎是可行的,只要你是确定,你的字符串就会是"True""False":

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

我通常不建议这样做,但它是完全内置的,可以根据您的需求来选择。

转换为bool类型的通常规则是,一些特殊的字面量(False00.0()[]{})是假的,然后其他的都是真的,所以我推荐如下:

def boolify(val):if (isinstance(val, basestring) and bool(val)):return not val in ('False', '0', '0.0')else:return bool(val)

这里有一个复杂的,内置的方法来得到许多相同的答案。请注意,尽管python认为""为假,所有其他字符串为真,但TCL对此有非常不同的想法。

>>> 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 getreturn self._tk.getboolean(self._tk.globalgetvar(self._name))_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']">>>

这样做的一个好处是,它对您可以使用的值是相当宽容的。它在将字符串转换为值方面很懒惰,在接受和拒绝什么方面很卫生(请注意,如果在tcl提示符下给出上述语句,它将删除用户的硬盘)。

不好的是,它要求Tkinter可用,这通常是正确的,但不是普遍的,更重要的是,需要创建Tk实例,这是相对繁重的。

什么被认为是真或假取决于Tcl_GetBoolean的行为,它认为# 100、01和02是假的,而03、04、05和06是真的,不区分大小写。任何其他字符串,包括空字符串,都会导致异常。

您可能已经有了一个解决方案,但对于其他人来说,他们正在寻找一种方法,将值转换为布尔值,使用“标准”假值,包括None,[],{}和“”,除了false, no和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
def str2bool(str):if isinstance(str, basestring) and str.lower() in ['0','false','no']:return Falseelse:return bool(str)

想法:检查你是否希望字符串被计算为False;否则bool()对于任何非空字符串返回True。

下面是我用来评估字符串真实性的东西:

def as_bool(val):if val:try:if not int(val): val=Falseexcept: passtry:if val.lower()=="false": val=Falseexcept: passreturn bool(val)

结果与使用eval大致相同,但更安全。

这是我的版本。它同时检查正值和负值列表,对于未知值引发异常。它不接收字符串,但任何类型都可以。

def to_bool(value):"""Converts 'something' to boolean. Raises exception for invalid formatsPossible 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 Trueif str(value).lower() in ("no",  "n", "false", "f", "0", "0.0", "", "none", "[]", "{}"): return Falseraise Exception('Invalid value for boolean conversion: ' + str(value))

示例:

>>> 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_boolException: 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_boolException: Invalid value for boolean conversion: Wasssaaaaa>>>

dict(实际上是defaultdict)为你提供了一种非常简单的方法:

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

将这个方法定制为您想要的确切转换行为非常容易——您可以用允许的Truthy和Falsy值填充它,并在没有找到值时让它引发异常(或返回None),或默认为True,或默认为False,或任何您想要的。

这是我写的版本。将其他几个解决方案合并为一个。

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 Trueif value.lower() in ("no",  "n", "false", "f", "0", ""):return Falseraise Exception('Invalid value for boolean conversion: ' + value)return bool(value)

如果它得到一个字符串,它期望特定的值,否则引发异常。如果它没有得到一个字符串,就让bool构造函数来计算它。测试这些案例:

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

我喜欢使用三元运算符,因为它对于不应该超过一行的东西来说更简洁一些。

True if my_string=="True" else False

我不同意任何解决办法,因为他们太宽容了。在解析字符串时,这通常不是您想要的结果。

这里是我使用的解决方案:

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

结果是:

>>> [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_boolValueError: '' is no recognized as a boolean value

澄清一下,因为我的回答似乎冒犯了某人:

关键在于,您不希望只测试一个值,并假设另一个值。我不认为你总是想把所有东西都映射到未解析的值。这会产生容易出错的代码。

如果你知道你想要什么,就把它编码进去。

JSON解析器在将字符串转换为合理的python类型时也很有用。

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

一个很酷,简单的技巧(基于@Alan Marchiori发帖),但使用yaml:

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

如果这个范围太广,可以通过测试类型结果进行细化。如果yaml返回的类型是str,那么它就不能转换为任何其他类型(我能想到的类型),所以可以单独处理它,或者让它为真。

我不会对速度做任何猜测,但因为我在Qt gui下使用yaml数据,这有一个很好的对称性。

我知道这是一个老帖子,但一些解决方案需要相当多的代码,以下是我最终使用的:

def str2bool(value):return {"True": True, "true": True}.get(value, False)

警告:此答案从Python 3.12起不再有效(从3.10起已弃用)

使用:

bool(distutils.util.strtobool(some_string))
  • # 0: # 1
  • # 0: # 1
  • Python在= 3.12:由于PEP 632,不再是标准库的一部分

真值是y, yes, t, True, on和1;假值为n, no, f, False, off和0。如果val为其他值,则引发ValueError。

请注意,distutils.util.strtobool()返回整数表示,因此需要用bool()包装它以获得布尔值。

该版本保留了int(value)等构造函数的语义,并提供了一种简单的方法来定义可接受的字符串值。

def to_bool(value):valid = {'true': True, 't': True, '1': True,'false': False, 'f': False, '0': False,}
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 casesassert 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

如果你知道你的输入将是"True"或其他东西,那么为什么不使用:

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

我必须这么做……所以,也许姗姗来迟——但有人可能会发现它很有用

def str_to_bool(input, default):"""| Default | not_default_str | input   | result| T       |  "false"        | "true"  |  T| T       |  "false"        | "false" |  F| F       |  "true"         | "true"  |  T| F       |  "true"         | "false" |  F
"""if default:not_default_str = "false"else:not_default_str = "true"
if input.lower() == not_default_str:return not defaultelse:return default

通过使用Python内置的eval()函数和.capitalize()方法,您可以将任何“true”/“false”字符串(不管初始大写)转换为true Python布尔值。

例如:

true_false = "trUE"type(true_false)
# OUTPUT: <type 'str'>
true_false = eval(true_false.capitalize())type(true_false)
# OUTPUT: <type 'bool'>

如果你可以控制返回true/false的实体,一种选择是让它返回1/0而不是true/false,那么:

# 0

额外的转换到int处理来自网络的响应,这些响应总是字符串。

2021年更新:"——这是一种天真的看法。它取决于库使用的序列化协议。高级库(大多数web开发人员使用的库)的默认的序列化通常是在序列化为字节之前转换为字符串。然后在另一边,它从字节反序列化为字符串,所以你丢失了任何类型信息。

.blink {color: yellow;animation: blink-animation 0.5s infinite;}@keyframes blink-animation {25% {background-color: black;color: cyan;}50% {background-color: black;color: red;}75% {background-color: black;color: lime;}}
<h1 class="blink">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.</h1>

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

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

不过,只有在确定字符串的内容时才使用此方法,因为如果字符串不包含有效的Python,它将抛出异常,并且还将执行字符串中包含的代码。

还有一种选择

from ansible.module_utils.parsing.convert_bool import booleanboolean('no')# Falseboolean('yEs')# Trueboolean('true')# True

使用包str2bool pip install str2bool

如果你像我一样,只需要布尔从变量是字符串。你可以用蒸馏液作为0号。但是我不能按照他的建议导入和使用模块。

相反,我最终在python3.7中以这种方式使用它

distutils string to bool in python

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

# 0👍

我使用

# functiondef 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]]"""

注:千万不要使用 eval(),如果它直接或间接地从用户那里获取输入,因为它很容易被滥用:

# 0

但干杯!研究还发现,eval()并不是邪恶的,受信任的代码也完全可以接受。您可以使用它将布尔字符串(如"False""True")转换为布尔类型。


我想分享我的简单解决方案:使用eval()。它将字符串TrueFalse转换为适当的布尔类型,如果字符串的标题格式TrueFalse总是第一个字母大写,否则该函数将引发一个错误。

如。

>>> eval('False')False
>>> eval('True')True

当然,对于动态变量,您可以简单地使用.title()来格式化布尔字符串。

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

这将抛出一个错误。

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

我还被要求将一个函数的输入更改为bool,而在string中主要输入仅为TrueFalse。所以,我只是这样编码:

def string_to_bool(s):bool_flag = Trueif s == "False":bool_flag = Falseelif s == "True":bool_flag = Trueelse:print("Invalid Input")return bool_flag

你也可以查看TrueFalse的缩写,如Y/Ny/n等。

你也可以计算任何字符串字面值:

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

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

我完全同意@Jacob\ Gabrielson的解决方案,但问题是ast.literal_eval只适用于字符串值TrueFalse,而不是truefalse。所以你只需要使用第5条就可以了

import astast.literal_eval("false".title())# orast.literal_eval("False".title())

通过使用下面的简单逻辑,你可以将字符串a = 'true''false'转换为布尔值。

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

如果a == 'true',则设置a=True,如果a == 'false',则设置a=False

对于pydantic,有一个优雅的解决方案:

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

使用这个解决方案:

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

我们可能需要捕捉'true'不区分大小写,如果是这样的话:

>>> x="TrUE">>> x.title() == 'True'True
>>> x="false">>> x.title() == 'True'False

还要注意,对于任何其他既不是真也不是假的输入,它将返回False

在python 3.10版本中,你可以这样做;

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

match-statement等价于c++中的switch。

在有限的情况或情况下,您可以对正在处理的数据做出强有力的假设。然而,由于自定义对象可以覆盖Python中的__eq__相等性检查,因此存在一个重大缺陷。看看下面这个刻意简化的玩具例子:

In [1]: class MyString:...:     def __init__(self, value):...:         self.value = value...:     def __eq__ (self, obj):...:         if hasattr(obj, 'value'):...:             return obj.value == self.value...:         return False...:
In [2]: v = MyString("True")
In [3]: v == "True"Out[3]: False

如果您想象有人从string类型继承了MyString,或者实现了各种原生字符串方法,如repr等,因此MyString实例的行为大多与字符串完全相同,但在相等性检查中有特殊的额外value步骤,那么简单地使用== 'True'将会失败,从用户的角度来看,这很可能是一个无声的失败。

这就是为什么强制type执行您想要执行的相等性检查的确切性质,将其封装到一个helper函数中,并依赖于那种"已注册的"验证事物的方法。例如,对于MyString,你可以这样写,

def validate(s):if isinstance(s, str):return s == 'True'elif isinstance(s, MyString):return s.value == 'True' # <-- business logic...raise ValueError(f"Type {type(s)} not supported for validation.")

或者另一种常用的模式是反向透视图,其中您只为验证定义了一种行为,但是您有一个helper函数,它将强制转换为适合于该单一验证行为的类型,例如

def to_str(s):if isinstance(s, str):return selif isinstance(s, MyString):return s.value...raise ValueError(f"Unsupported type {type(s)}")
def validate(s):return to_str(s) == 'True'    

它可能看起来像我们添加了很多样板文件和冗长的内容。我们可以灵活地表达批评,“如果你可以只写s == 'True',为什么要写那么多?”-但它忽略了一点,即当你验证某事时,你需要确保所有的前提条件都适用于验证逻辑。如果你可以假设一些数据是简单的str类型,你不需要做任何先决条件(比如类型)检查,这很好——但这是非常罕见的情况,将这个问题的一般情况描述为可以进行一次超级简短的相等性检查可能会产生误导。