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


744

有谁知道如何在Python中从字符串转换为布尔值?我找到了这个链接。但这似乎不是正确的方法。即使用内置功能等

我之所以这样问,是因为我int("string")从这里学到了。但是当尝试bool("string")它总是返回True

>>> bool("False")
True

2
我为此专门创建了一个微库,其中还包括一些外来词,例如波兰语的“ tak”,汉语中的“'是”将评估为True。如果未明确显示,则true-ish将求值为False。欢迎提出建议。Github链接:github.com/kmonsoor/str2bool
kmonsoor

18
@jzwiener的答案使用了python标准库中的函数,distutils.util.strtobool(some_string)而不是重新发明轮子并编写一堆必须引起人们注意的代码。从技术上讲,输出是int带值的类型01->如果您确实想要/需要,bool则可以使用将该函数包装起来bool(distutils.util.strtobool(some_string))
Trevor Boyd Smith,

1
pip install str2bool
Symon

只是抬头。distutils.util.strtobool与@kmonsoor的解决方案不同,它无法处理外国的是/否,但是@kmonsoor不能处理使用外语(例如VEROFALSO)使用True / False的Excel制作的CSV文件。因此,有时需要重新设计轮子。
Matteo Ferla

Answers:


836

实际上,您只需将字符串与希望接受的代表true的字符串进行比较,就可以做到这一点:

s == 'True'

或检查一堆值:

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

使用以下内容时请小心:

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

空字符串的计算结果为False,但其他所有结果的计算结果为True。因此,不应将其用于任何类型的解析目的。


48
+1:没有比这更简单的了s == "True"。但是我已经看到人们对此一无所知。def convert(s):如果s ==“ True”:返回True;返回False。
S.Lott

24
与if / else相比,我更喜欢返回s ==“ True”
Dana

26
如果s ==“ True”:返回True elif s ==“ False”:返回False else:返回加薪
未知

9
将字符串解析为布尔值已在distutils.util.strtobool中实现:stackoverflow.com/a/18472142/923599
jzwiener

9
我知道这是一个非常老的话题,但是我想证明我花了4个小时来调试我的代码。我的错误是试图投下bool("False")。它将始终转换为True
Ev。

304

采用:

bool(distutils.util.strtobool(some_string))

真实值为y,y,t,true,on和1;false值是n,no,f,false,off和0。如果val是其他值,则引发ValueError。

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


38
不幸的是,它返回1/ 0不是True/ False,因此您需要将结果包装在bool()中以获取实际的布尔值:bool(distutils.util.strtobool(some_string))
Mariusz Jamro 2014年

2
该功能非常诱人。如果它处理整数和Nonestr(None)作为输入,那将是完美的。
MarkHu 2014年

20
我更喜欢这个,而不是投票更高的答案……它来自stdlib,并且确实满足要求。只要没有做类似...之类的坏事情,通常就没有理由需要/ bool而不是1/ 0if x == False并且如果您正在处理ints和Nones 且不需要特殊功能,则只需检查它们即可。直接if myint:if not maybe_none_var:
Anentropic 2014年

4
@Secator boolint
Anentropic 2014年

1
要为某人节省一些Google搜索错误,请执行以下操作:导入distutils和import distutils.util,以使其正常工作。
爱德华·B。

267
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单词列表。然后,如果它不在两个列表中,则可能引发异常。


29
使用str(v).lower()而不是v.lower()几乎无法进行增强。然后,即使它不是字符串,它也可以工作,例如1,0
kmonsoor

RE:显式处理true / false,如果字符串不匹配,您还可以提供默认值,就像true / false命令行提示的工作方式一样:继续吗?(y / N)
Johnus's

113

JSON解析器通常也可用于将字符串转换为合理的python类型。

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

31
请注意,此方法仅在小写的情况下有效。如果是大写,则不能。您必须致电.lower()
CppLearner 2013年

107

从Python 2.6开始,现在有ast.literal_eval

>>>导入AST
>>>帮助(ast.literal_eval)
帮助ast模块中的literal_eval函数:

literal_eval(node_or_string)
    安全地评估表达式节点或包含Python的字符串
    表达。提供的字符串或节点只能由以下内容组成
    Python文字结构:字符串,数字,元组,列表,字典,布尔值,
    和没有。

因为你这似乎工作,只要确保你的字符串将是两种"True""False"

>>> ast.literal_eval(“ True”)
真正
>>> ast.literal_eval(“ False”)
假
>>> ast.literal_eval(“ F”)
追溯(最近一次通话):
  文件“”,第1行,位于 
  文件“ /opt/Python-2.6.1/lib/python2.6/ast.py”,第68行,位于literal_eval中
    返回_convert(node_or_string)
  _convert中的文件“ /opt/Python-2.6.1/lib/python2.6/ast.py”,第67行
    引发ValueError('格式错误的字符串')
ValueError:格式错误的字符串
>>> ast.literal_eval(“'False'”)
'假'

我通常不建议这样做,但是它是完全内置的,根据您的要求可能是正确的选择。


1
不确定此解决方案的一般适用性,但是以一般方式来说非常好。+1!
SingleNegationElimination

3
Gaah,这太恐怖了!再说一遍,您确实说过您不推荐这样做,它确实可以很好地回答问题。好发现!
Vanessa Phipps 2013年

4
不幸的是,它无法处理这种情况>>> ast.literal_eval('true')或ast.literal_eval('TRUE')引发>>>提高ValueError('格式错误的字符串')尽管ast.literal_eval(to_test .title())
Bhushan

对于这个特定的问题,这不是一个很好的解决方案,但是……哇,literal_eval真有用!列出,字典等的字符串
travc 2014年

它对Unicode起作用吗?在我的Django视图中,我有一个要更改为布尔值的传入值,它给出了格式错误的字符串异常。
Prakhar Mohan Srivastava 2015年

48

如果您知道字符串为"True"or "False",则可以使用eval(s)

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

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


5
那个弦将来自某个地方。if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
nurettin

4
@nurettin,因此,只有在您确定字符串的内容时,我的评论才使用它。
乔尔·克罗特

17

此版本保留了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 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

3
Nit:您的最后一个“测试用例”将在第一次调用时出错,而不会测试其他调用。此外,如果引发错误,它将不会失败。
augurar

12

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

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

样品运行:

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

一个人可能会被这种情况咬伤:to_bool(["hello"])如果[]得到支持,这应该是一个非常有效的电话
Rafael T

1
返回“异常:布尔转换的无效值:['hello']”,这是预期的并有文档说明。在我看来,空列表显然是错误的,但是['false']显然不是什么,因此我故意将其排除在外-这是一个功能,而不是错误。如果您想要的话,应该容易添加对非空列表返回true的支持。
Petrucio

1
确保您记录了它。但是在现实生活中人们永远不会打电话to_bool([])。取而代之的是,他会按照以下方式做一些事情:myList=someFunctionThatReturnAList`if(is_bool(myList)):...´所以一个人有一个列表,想知道这个列表是None还是为空。
拉斐尔T

为什么不尝试这样:>>> def a2b(arg):...默认= bool(arg)...如果isinstance(arg,str):...在['true','中返回arg.lower() t','yes','y','1'] ...其他:...返回默认值
ThePracticalOne 2013年

5
关键点:您可能应该首选ValueError而不是普通的Exception。
dshepherd 2015年

10

你总是可以做这样的事情

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

括号中的位将评估为False。这是无需执行实际函数调用的另一种方法。


1
val = "false"在此示例中的代码行是什么?为什么在那儿?这是什么意思?
S.Lott

9
我认为,这意味着42
地理

@Geo:我同意;但是那个陈述回答的问题是什么?
S.Lott

这正是我在寻找的内容,它从文件中评估输入字段并基于存储布尔值的结果。谢谢。
jimh

9

一个很酷的简单技巧(基于@Alan Marchiori发布的内容),但是使用了yaml:

import yaml

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

如果宽度太大,可以通过测试类型结果来完善它。如果yaml返回的类型是str,则不能将其强制转换为任何其他类型(无论如何我都可以想到),因此您可以单独处理它,也可以使其为true。

我不会对速度做出任何猜测,但是由于无论如何我都在Qt gui下使用yaml数据,所以这具有很好的对称性。


1
yaml模块是第三方库:PyYAML
Peter Wood,

8

我不同意这里的任何解决方案,因为它们太宽容了。这通常不是解析字符串时想要的。

所以这是我正在使用的解决方案:

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

结果:

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

只是要清楚一点,因为它看起来好像我的回答以某种方式冒犯了别人:

关键是您不想只测试一个值并假设另一个值。我不认为您总是想将所有内容绝对映射到未解析的值。产生易于出错的代码。

因此,如果您知道要编码的内容。


2
我认为您没有抓住要点:答案的目的是演示一般原则,而不是告诉提出问题的人确切的做法。最初问这个问题的人是在考虑什么实际上是一个简单的问题。
基思·高恩

8
@基思我不同意。重点是回答所提出的问题。
estani 2012年

1
问的问题是如何将字符串转换为布尔值。那就是我回答的问题。我不知道原始海报的有效布尔值字符串是什么,您也不知道。这就是为什么说明一般原则比给发布者完整的答案更重要。原始海报不需要向他们说明所有内容:它们仅需展示一般原则即可。由此,任何有能力的人都会得到您的答案。
基思·高恩

2
@dshepherd isinstance在那里,确保我正在解析期望的结果。我正在解析字符串,因此偶然返回“ 1”的方法car_race.lower()不应返回true,它应该引发ValueError。但这在其他情况下可能就足够了。
estani 2015年

2
@CivFan有趣的一点。尽管我尝试过,但对我来说读起来并不好。elif由于返回字是多余的,但是它无需扫描即可提供更多信息return。但是,只有我一个人,如果有PEP风格违规,我会进行更改。没有任何其他限制,我们应该始终追求可读性(标准做到这一点)。感谢您的注意和有趣的评论!
estani 2015年

7

dict(实际上是defaultdict)为您提供了一种非常简单的方法来完成此操作:

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

将该方法定制为所需的确切转换行为非常容易-您可以使用允许的Truthy和Falsy值填充该方法,并在找不到值时将其引发异常(或返回None),或者默认为True,或默认为False或您想要的任何值。


5

您可能已经有了解决方案,但对于其他人,他们正在寻找一种方法,使用除false,no和0之外的“ Non”,[],{}和“”等“标准” false值将值转换为布尔值。

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
最好使用集合,not in并且您选择的错误项有些特殊。
SilentGhost 2010年

5

您可以简单地使用内置函数eval()

a='True'
if a is True:
    print 'a is True, a type is', type(a)
else:
    print "a isn't True, a type is", type(a)
b = eval(a)
if b is True:
    print 'b is True, b type is', type(b)
else:
    print "b isn't True, b type is", type(b)

和输出:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>

1
这仅在测试值是有效python时有效。“ true”和“ false”将引发异常。
Gordon Bean

13
此外,使用'eval'进行解析是一个非常不好的习惯,因为eval将在字符串中运行任意代码。在某些情况下,这可能会带来巨大的安全性。
Christopher Barber

7
这是一个非常糟糕的答案。评估任意表达式以解析布尔值不是一个好方法。
augurar

5

另一个选择

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

但是在生产中,如果不需要ansible及其所有依赖关系,一个好主意是查看其源代码并复制所需逻辑的一部分。


4

进行浇铸,一个布尔值,通常的规则是,一些特殊的文字(False00.0()[]{})都是假的,然后一切是真实的,所以我提出以下建议:

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

3

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

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)

如果它得到一个字符串,则它期望特定的值,否则引发Exception。如果没有得到字符串,只需让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),
    ]

使用str代替type('')
pppery


3

我用

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

# test cases
[[x, toBool(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]]
"""

2

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

True if myString=="True" else False

1
比my_string =='True'更简洁?
S. de Melo

2

我意识到这是一篇旧文章,但是某些解决方案需要大量代码,这就是我最终使用的内容:

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

7
这在功能上等效于,并比以下更为复杂:('True','true')中的返回值
Keith Gaughan


1

如果您喜欢我,只需要来自字符串的变量中的布尔值即可。您可以使用@jzwiener前面提到的distils。但是,我无法按照他的建议导入和使用该模块。

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

distutils字符串在Python中布尔

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

distutils是python std lib的一部分,因此无需安装。太好了!👍


1

我想分享我的简单解决方案:使用eval()。这将字符串转换True以及False如果字符串恰恰是在标题格式正确的布尔类型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

0

这是一个毛茸茸的方法,旨在获得许多相同的答案。请注意,尽管python认为""是false,而所有其他字符串都为true,但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 get
    return self._tk.getboolean(self._tk.globalgetvar(self._name))
_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']"
>>> 

这样做的好处是,您可以宽恕可以使用的值。关于将字符串转换为值是懒惰的,对于接受和拒绝的内容也很不合时宜(请注意,如果上述声明是在tcl提示符下给出的,则会擦除用户的硬盘)。

坏的事情是,它要求Tkinter可用,这通常是正确的,但并非普遍如此,更重要的是,它要求创建一个Tk实例,它相对较重。

什么被认为是真还是假取决于的行为Tcl_GetBoolean,它认为0falsenooff为假1trueyeson是真实的,不区分大小写。任何其他字符串(包括空字符串)都会导致异常。


0
def str2bool(str):
  if isinstance(str, basestring) and str.lower() in ['0','false','no']:
    return False
  else:
    return bool(str)

想法:检查您是否希望将字符串评估为False;否则,bool()对于任何非空字符串都返回True。


0

我汇总了以下内容以评估字符串的真实性:

def as_bool(val):
 if val:
  try:
   if not int(val): val=False
  except: pass
  try:
   if val.lower()=="false": val=False
  except: pass
 return bool(val)

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


0

我只需要这样做...所以聚会晚了-但有人可能会觉得有用

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 default
    else:
        return default

0

如果您可以控制返回true/ 的实体,false则可以选择使它返回1/ 0而不是true/ false,然后:

boolean_response = bool(int(response))

用于int处理来自网络的响应(通常是字符串)的额外转换。


-5

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

例如:

true_false = "trUE"
type(true_false)

# OUTPUT: <type 'str'>

true_false = eval(true_false.capitalize())
type(true_false)

# OUTPUT: <type 'bool'>

4
如果该字符串包含#\nshutil.rmtree('/someImportantDirectory')?(不要尝试!)
mastov

@mastov-荒唐的downvote。显然,如果您无法控制传入的字符串,则需要采取任何代码一样的预防措施。但是,如果您确实控制工作流程,那么这是一个可行的简单解决方案。不要将一个并非完美的解决方案与一个错误的答案混为一谈。
elPastor

1
除了不提危险(这已经使这个答案不好)之外:您是否打算事先清理输入内容?这将扼杀该方法的简单性,这是它的主要优点。
mastov

4
使用eval这种简单的功能只是寻求漏洞。
mastov

1
并非所有代码。但是特别是将字符串转换为其他类型的代码通常无法控制的。通常,您甚至可能没有意识到这一点。您可能会说:“这是我的数据库(或配置文件),是我系统控制下的一部分。” 然后授予其他模块对数据库的访问权限,因为:“有什么害处?只有带有字符串的某些表。” 但是使用eval这些字符串可能会帮助某人接管整个系统。
mastov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.