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

Joa*_*nge 653 python string boolean

有没有人知道如何在Python中从字符串转换为布尔值?我找到了这个链接.但它看起来不是一个正确的方法.即使用内置功能等.

编辑:

我问这个的原因是因为我int("string")从这里学到了.我试过bool("string")但总是得到True.

>>> bool("False")
True
Run Code Online (Sandbox Code Playgroud)

Kei*_*han 745

实际上,您只需将字符串与您希望接受的任何字符串进行比较即可,因此您可以这样做:

s == 'True'
Run Code Online (Sandbox Code Playgroud)

或者检查一大堆值:

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

使用以下内容时要小心:

>>> bool("foo")
True
>>> bool("")
False
Run Code Online (Sandbox Code Playgroud)

空字符串计算到False,但其他所有内容都计算为True.所以这不应该用于任何类型的解析目的.

  • +1:没有多少比`s =="True"更简单.但是我看到人们把这弄得一团糟.def convert(s):if s =="True":return true; 返回False. (43认同)
  • 如果s =="True":返回True elif s =="False":返回False否则:return raise (23认同)
  • 我更喜欢在if/else上返回s =="True" (20认同)
  • 已经在distutils.util.strtobool中实现了将字符串解析为布尔值:http://stackoverflow.com/a/18472142/923599 (8认同)
  • 我知道这是一个非常古老的主题,但我想证明我花了4个小时试图调试我的代码.我的错误是试图施放`bool("False")`.它将始终转换为"True". (6认同)
  • @estani:不,我没有错过这个错误的部分.你错过了我的答案,这是为了演示简单检查提供的字符串是否在有效值中的基本原则.你会注意到我没有提供完成工作的功能:那是故意的. (4认同)
  • @Dana:每个人都应该。if x: return True 是一件可怕的事情。唯一更糟糕的是如果 x: 返回 False。 (2认同)
  • 显然你应该使用`set`而不是`list`作为真正的字符串... http://stackoverflow.com/a/7110296/202168 (2认同)
  • 那要看.对于非常短的东西,扫描列表或元组可能会更快.这是在扫描列表/元组所花费的时间长度与散列对象查找所花费的时间之间的权衡,并且还必须考虑创建集合对象本身所需的时间.这不是我太担心的东西,除非它真的需要优化.配置文件,然后优化. (2认同)
  • 我建议在真值列表中添加布尔值“True”。这样,如果 s 之前已经转换为布尔值,则结果将为 True 而不是 False。`s in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', '当然', 'uh-huh', True]` (2认同)

Bri*_*ndy 249

def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")
Run Code Online (Sandbox Code Playgroud)

然后像这样调用它:

>>> str2bool("yes")
True
>>> str2bool("no")
False
>>> str2bool("stuff")
False
>>> str2bool("1")
True
>>> str2bool("0")
False
Run Code Online (Sandbox Code Playgroud)

__CODE__

def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")
Run Code Online (Sandbox Code Playgroud)

__CODE__

>>> str2bool("yes")
True
>>> str2bool("no")
False
>>> str2bool("stuff")
False
>>> str2bool("1")
True
>>> str2bool("0")
False
Run Code Online (Sandbox Code Playgroud)

__CODE__

def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")
Run Code Online (Sandbox Code Playgroud)

__CODE__

>>> str2bool("yes")
True
>>> str2bool("no")
False
>>> str2bool("stuff")
False
>>> str2bool("1")
True
>>> str2bool("0")
False
Run Code Online (Sandbox Code Playgroud)

__CODE__


明确处理true和false:

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

  • 可以使用**str(v).lower()**而不是**v.lower()**来进行少量增强.然后,即使它不是字符串,它也可以工作,例如1,0 (22认同)

jzw*_*ner 246

只需使用:

distutils.util.strtobool(some_string)
Run Code Online (Sandbox Code Playgroud)

http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

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

  • 不幸的是,这会返回`1` /`0`而不是'True` /`False`,所以你需要将结果包装在bool()中以获得实际的布尔值:`bool(distutils.util.strtobool(some_string))` (30认同)
  • 我更喜欢这个更高的投票答案......它来自stdlib并完全符合要求.只要你没有像`if x == False`那样做坏事......并且如果你正在处理`,那么通常没有理由需要一个实际的`bool`而不是`1` /`0`. int`s和`你不需要一个特殊的函数,你可以直接检查它们`如果myint:`或`if not maybe_none_var:` (17认同)
  • 为了避免某些人在谷歌上搜索错误: import distutils 和 import distutils.util 才能正常工作。 (17认同)
  • 请注意,distutils 包自 python 3.10 起已被弃用,并将在版本 3.12 中删除。 (17认同)
  • @Secator`bool`是`int`的子类 (4认同)
  • 为了扩展@jan-di的评论,在[PEP 632](https://peps.python.org/pep-0632/)中明确调用了`distutils.util.strtobool`,因为在Python中没有得到等效的实现3.12: > 对于这些功能以及此处未提及的任何其他功能,您需要自己重新实现该功能。旧文档可以在 https://docs.python.org/3.9/distutils/apiref.html >> distutils.dir_util.create_tree > distutils.util.change_root > distutils.util.strtobool 找到,不幸的是,因为这是我的长期以来用于此目的的首选功能。 (3认同)
  • 该功能非常诱人。如果它处理整数并将`None`和`str(None)`作为输入,那将是完美的。 (2认同)
  • 如果 `import distutils.util` 失败并出现 _AttributeError: module 'distutils' has no attribute 'util'_,以下语句可能会有所帮助:`from distutils.util import strtobool`。很奇怪,但我曾经遇到过这种情况。 (2认同)

Jac*_*son 104

从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 Python
    expression.  The string or node provided may only consist of the following
    Python 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, 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'

我通常不推荐这个,但它是完全内置的,根据您的要求可能是正确的.

  • 不幸的是它没有处理这种情况>>> ast.literal_eval('true')或ast.literal_eval('TRUE')引发>>>引发ValueError('malformed string')尽管ast.literal_eval(to_test)修复很简单.标题()) (4认同)
  • 高啊,那太吓人了!再说一遍,你_did_说你不推荐它,并且_does_整齐地回答了这个问题.很好找! (3认同)
  • 不确定这个解决方案的普遍适用性,但它非常好,以一般的方式。+1! (2认同)

小智 102

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

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此方法仅在小写时才有效.如果它是大写的,你就不能.你必须调用``.lower()`` (28认同)
  • 但请注意,不会验证返回类型是否为布尔值。`json.loads("[42]".lower()) -> [42]` (3认同)

Joe*_*eau 35

如果您知道该字符串将是"True"或者"False",您可以使用eval(s).

>>> eval("True")
True
>>> eval("False")
False
Run Code Online (Sandbox Code Playgroud)

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

  • @nurettin,因此我的评论是只有在您确定字符串的内容时才使用它。 (4认同)
  • 那个弦将来自某个地方。如果eval(os.environ [“ LOL”]):#可能永远不会到达这里。可能还会从您公司的信用卡中扣款。` (3认同)
  • 拜托拜托拜托,上面有很多更安全的选项,为什么你要使用 `eval` 进行简单的字符串比较,你永远无法 100% 确定一段代码将保持不变并且随着时间的推移表现相同但有一个很小的机会,你把“eval”留在那里,然后灾难汤就准备好了 (3认同)
  • 我的一部分认为大写字母“警告”是正确的。另一方面,另一部分说,如果有人愚蠢到复制粘贴答案而不考虑它的真正作用,他们就应该被黑客攻击 (3认同)
  • 这是我在谷歌上搜索的正确答案。eval("True") = True 且 eval("False") = False。简单的。我用它来 ping 布尔值的配置文件。 (2认同)

Yan*_*ann 22

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

为了pydantic >=2

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

>>> TypeAdapter(bool).validate_python("off")
False
Run Code Online (Sandbox Code Playgroud)

为了pydantic <2

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

>>> pydantic.parse_obj_as(bool, "off")
False
Run Code Online (Sandbox Code Playgroud)


Mic*_*ond 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
Run Code Online (Sandbox Code Playgroud)

  • Nit:您的最后一个“测试用例”将在第一次调用时出错,而不会测试其他调用。此外,如果 *not* 引发错误,它也不会失败。 (4认同)

Roe*_*oel 17

更新

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

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

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

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

例如

>>> eval('False')
False

>>> eval('True')
True
Run Code Online (Sandbox Code Playgroud)

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

>>> x = 'true'
>>> eval(x.title())
True
Run Code Online (Sandbox Code Playgroud)

这将引发错误。

>>> 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
Run Code Online (Sandbox Code Playgroud)

  • 哇,对于发现此内容的任何人:除了简单脚本之外,请勿将其用于其他任何用途。如果您在任何严肃的应用程序中使用它,您将面临各种不需要的代码执行。想象一个场景,您解析用户的输入并将字符串转换为布尔值,您可以使用它。在这种情况下,攻击者基本上可以执行您的代码执行的任何操作。不相信我?试试这个: import os eval("os.getcwd()") (11认同)
  • @MartinBraun啊,是的研究发现你可以执行这个 `eval('os.system('rm -rf /')')` 并且它会删除该目录中的所有文件。然而,“eval()”对于受信任的代码来说是完全可以的,它并不是真正的邪恶。所以我最好记下注意事项。 (2认同)

Pet*_*cio 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))
Run Code Online (Sandbox Code Playgroud)

样品运行:

>>> 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
>>>
Run Code Online (Sandbox Code Playgroud)

  • 小点:你应该更喜欢[ValueError](https://docs.python.org/3/library/exceptions.html#ValueError)而不是普通的Exception. (3认同)

hel*_*dre 10

你总能做点什么

myString = "false"
val = (myString == "true")
Run Code Online (Sandbox Code Playgroud)

parens中的位将评估为False.这只是另一种方法,无需进行实际的函数调用.

  • 我认为这意味着42. (8认同)

Raf*_*afe 9

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

import yaml

parsed = yaml.load("true")
print bool(parsed)
Run Code Online (Sandbox Code Playgroud)

如果这个太宽,可以通过测试类型结果来改进它.如果yaml返回的类型是str,那么它不能被转换为任何其他类型(我能想到的任何类型),所以你可以单独处理它,或者只是让它成为真.

我不会在速度上做任何猜测,但是因为我正在使用Qt gui下的yaml数据,所以它具有很好的对称性.

  • `yaml` 模块是第三方库:[PyYAML](https://github.com/yaml/pyyaml) (2认同)

est*_*ani 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)
Run Code Online (Sandbox Code Playgroud)

结果如下:

>>> [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
Run Code Online (Sandbox Code Playgroud)

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

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

所以,如果你知道你想要什么代码.

  • @Keith我不同意.关键在于回答这个问题. (8认同)
  • 我认为你错过了重点:答案的重点是展示一般原则,而不是告诉那些问他们应该怎么做的人.最初问这个问题的人就是在思考什么是一个简单的问题. (2认同)
  • 提出的问题是如何将字符串转换为布尔值。这就是我回答的问题。我不知道什么被认为是原始海报的有效布尔字符串,你也不知道。这就是为什么展示一般原则比给发布者提供完整答案更重要。最初的发布者不需要向他们阐明所有内容:他们所需要的只是展示一般原则。由此,任何有能力的人都会得到你的答案。 (2认同)
  • @dshepherd isinstance确保我正在解析我的期望.我正在解析字符串,所以方法car_race.lower()偶然返回'1'不应该返回true,它应该抛出一个ValueError.但在其他情况下可能就足够了. (2认同)
  • @CivFan有趣的一点.虽然我尝试过,但它看起来并不那么好(对我来说).由于返回单词,`elif`是多余的,但它为您提供了更多信息,而无需扫描`return`.但这只是我,如果有PEP风格违规,我会改变它.在没有任何其他约束的情况下,我们应该始终追求可读性(标准也是如此).感谢您的提醒和有趣的评论! (2认同)

小智 8

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

a = a.lower() == 'true'
Run Code Online (Sandbox Code Playgroud)

if a == 'true'then 将会设置a=True,并且 if a == 'false'then a=False


MrH*_*DEn 6

我用

# 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]]
"""
Run Code Online (Sandbox Code Playgroud)


小智 5

你可能已经有了一个解决方案,但对于那些正在寻找一种方法,使用"标准"错误值将值转换为布尔值的其他人,包括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
Run Code Online (Sandbox Code Playgroud)


Nat*_*ate 5

dict(真的,一个默认的dict)为你提供了一个非常简单的方法来实现这个技巧:

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
Run Code Online (Sandbox Code Playgroud)

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


lum*_*tor 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)
Run Code Online (Sandbox Code Playgroud)

和输出:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>
Run Code Online (Sandbox Code Playgroud)

  • 此外,使用'eval'进行解析是一个非常糟糕的习惯,因为eval将在字符串中运行任意代码.在某些情况下,这可能会带来巨大的安全性. (13认同)
  • 这是一个非常糟糕的答案.评估任意表达式来解析布尔值不是一个好方法. (7认同)

Dan*_*men 5

如果您知道您的输入将是其中之一"True"或其他内容,那么为什么不使用:

def bool_convert(s):
    return s == "True"
Run Code Online (Sandbox Code Playgroud)


Sam*_*yek 5

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

boolean_response = bool(int(response))

int用于处理来自网络的响应的额外转换,这些响应始终是字符串。

2021 年更新:“始终是字符串”——这是一个天真的观察。这取决于库使用的序列化协议。高级库(大多数 Web 开发人员使用的库)的默认序列化通常是在序列化为字节之前转换为字符串。然后在另一边,它从字节反序列化为字符串,因此您丢失了任何类型信息。


Mat*_*cia 5

又一个选择

from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True
Run Code Online (Sandbox Code Playgroud)