ChatGPT解决这个技术问题 Extra ChatGPT

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

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

>>> bool("False")
True
我为此创建了一个微型图书馆,其中还包括一些外来词,例如波兰语的“tak”,普通话中的“'是的”将评估为True。如果没有明确地 true-ish 将评估为 False。欢迎提出建议。 Github 链接:github.com/kmonsoor/str2bool
但是在尝试 bool("string") 时,它总是返回 True...除了空字符串 bool("")

K
Keith Gaughan

真的,您只需将字符串与您期望接受的表示 true 的字符串进行比较,因此您可以这样做:

s == 'True'

或者检查一大堆值:

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

使用以下内容时要小心:

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

空字符串评估为 False,但其他所有字符串评估为 True。所以这不应该用于任何类型的解析目的。


+1:没有什么比 s == "True" 更简单的了。但我见过人们把这件事弄得一团糟。 def convert(s): if s == "True": return True;返回假。
我更喜欢 return s == "True" 而不是 if/else
if s == "True": return True elif s=="False": return False else: return raise
将字符串解析为布尔值已在 distutils.util.strtobool 中实现:stackoverflow.com/a/18472142/923599
我知道这是一个非常古老的话题,但我想证明我刚刚花了 4 个小时尝试调试我的代码。我的错误是尝试投射 bool("False")。它将始终转换为 True
S
ShadowRanger

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

利用:

bool(distutils.util.strtobool(some_string))

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

Python >=3,<3.12:https://docs.python.org/3/distutils/apiref.html#distutils.util.strtobool

Python >=3.12:由于 PEP 632,不再是标准库的一部分

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

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


这个功能很诱人。如果它处理整数和 Nonestr(None) 作为输入,那将是完美的。
与投票率较高的答案相比,我更喜欢这个……它来自 stdlib 并且完全符合要求。通常没有理由需要实际的 bool 而不是 1/0,只要您没有做像 if x == False 这样的坏事......并且如果您正在处理 intNone不需要特殊功能,直接查看if myint:if not maybe_none_var:即可
@Secator boolint 的子类
为了节省一些谷歌搜索的错误:导入 distutils 并导入 distutils.util 以使其正常工作。
请注意, distutils 包自 python 3.10 起已弃用,并将在 3.12 版中删除。
v
vinzee
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 单词列表。然后,如果它不在两个列表中,则可以抛出异常。


可以使用 str(v).lower() 代替 v.lower() 进行少许增强。然后,即使它不是字符串也可以工作,例如 1, 0
RE:显式处理真/假,如果字符串不匹配,您还可以提供默认值,就像真/假命令行提示的工作方式一样:继续? (是/否)
N
Nam G VU

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

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

但要小心,没有验证返回类型是布尔值。 json.loads("[42]".lower()) -> [42]
为什么需要 .lower()?当我不使用它时,例如 x = "False" j = json.loads(x),我收到错误 json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
N
Neuron

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

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


不确定这个解决方案的普遍适用性,但它非常好,以一般的方式。 +1!
嘎嘎,太可怕了!再说一次,你确实说你不推荐它,它确实巧妙地回答了这个问题。好发现!
不幸的是,它不能处理这种情况 >>>ast.literal_eval('true') 或 ast.literal_eval('TRUE') 引发 >>> raise ValueError('malformed string') 修复很简单,尽管 ast.literal_eval(to_test 。标题())
对于这个特定问题不是一个很好的解决方案,但是......哇,literal_eval 非常有用!要列出的字符串、dict 等。
它适用于 unicode 吗?在我的 Django 视图中,我有一个要更改为布尔值的传入值,它给出了格式错误的字符串异常。
J
Joel Croteau

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

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

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


该字符串将来自某个地方。 if eval(os.environ["LOL"]): #might never reach here. Might also charge your company's credit card.
@nurettin,因此我对仅在您确定字符串的内容时才使用它的评论。
拜托拜托,上面有很多更安全的选项,为什么要使用 eval 进行简单的字符串比较,您永远无法 100% 确定一段代码会随着时间的推移保持不变并表现相同但是您将 eval 留在那里的可能性很小,那么灾难汤就准备好了
这是我在谷歌上搜索的正确答案。 eval("True") = True 和 eval("False") = False。简单的。我用它来 ping 一个布尔值的配置文件。
我的一部分说大写字母“警告”是有序的。另一方面,另一部分说,如果有人愚蠢到复制粘贴答案而不考虑它的真正作用,那么他们就应该被黑
N
Neuron

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

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

但是干杯!研究还发现 eval() 不是邪恶的,它对于 TRUSTED CODE 来说是完全可以的。您可以使用它将 "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

哇,对于任何发现这个的人:不要将它用于除简单脚本之外的任何其他内容。如果您在任何严肃的应用程序中使用它,您将面临各种不需要的代码执行。想象一个场景,您解析来自用户的输入并将字符串转换为使用它的布尔值。在这种情况下,攻击者基本上可以做您的代码所做的任何事情。不相信我?试试这个: import os eval("os.getcwd()")
@MartinBraun 啊,是的,研究发现您可以执行此 eval('os.system(‘rm -rf /’)') 并删除该目录中的所有文件。然而 eval() 对于受信任的代码来说是完全可以的,它并不是真正的邪恶。所以我最好记下要小心。
literal_eval 怎么样?
M
Michael Richmond

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

Nit:您的最后一个“测试用例”将在第一次调用时出错,而不是测试其他用例。此外,如果没有引发错误,它也不会失败。
valid 的定义应放在函数外部,否则将在每次调用时重新构建 dict,从而首先消除使用 dict 的大部分性能优势。
P
Petrucio

这是我的版本。它检查正值和负值列表,引发未知值的异常。它不接收字符串,但任何类型都应该这样做。

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"]) 这应该是一个完全有效的调用
返回“异常:布尔转换的无效值:['hello']”,这是预期和记录的。在我看来,一个空列表显然是错误的,但 ['false'] 显然不是什么,所以我故意将其省略 - 这是一个功能而不是错误。如果这是您想要的,应该很容易添加对非空列表返回 true 的支持。
舒尔你记录了它。但在现实生活中,永远不会调用 to_bool([])。相反,他会按照以下方式做一些事情: myList=someFunctionThatReturnAList `if (is_bool(myList)):...´ 所以有一个列表并想知道这个列表是 None 还是空的。
为什么不试试这个: >>> def a2b(arg): ... default = bool(arg) ... if isinstance(arg, str): ... return arg.lower() in ['true', ' t', 'yes', 'y', '1'] ... else: ... 返回默认值
次要观点:您可能应该更喜欢 ValueError 而不是普通的异常。
N
Neuron

你总是可以做类似的事情

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

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


此示例中的 val = "false" 行在做什么?为什么会在那里?这是什么意思?
这正是我正在寻找的,评估文件中的输入字段并基于存储布尔值的结果。谢谢你。
N
Neuron

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

import yaml

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

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

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


yaml 模块是第三方库:PyYAML
对不受信任的输入 yaml.safe_load 而不是 yaml.load 提供更高的安全性
e
estani

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

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

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

为了清楚起见,因为看起来我的回答似乎以某种方式冒犯了某人:

关键是您不想只测试一个值并假设另一个值。我不认为您总是想将 Absolutely 一切都映射到未解析的值。这会产生容易出错的代码。

因此,如果您知道要在其中编写什么代码。


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

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 值填充它,并在未找到值或默认为 True 时让它引发异常(或返回 None),或默认为 False,或任何您想要的。


Y
Yann

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

import pydantic

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

N
Neuron

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

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

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


如果 a = '0' 怎么办?
@sagi - 然后我们可以使用: a = (str(a).lower() == 'true') | (str(a).lower() == '1')
但这也会将"truee"转换为 true。通常,如果输入无效,我们希望异常
N
Neuron

我用

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

C
Chris McMillan

您可能已经有了一个解决方案,但对于其他正在寻找一种使用“标准”假值(包括 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

最好使用集合,not in 并且您选择的虚假项目有些特殊。
M
Matt Kucia

另一种选择

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

C
Carl G

转换为 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)

S
Sam Malayek

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

boolean_response = bool(int(response))

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

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


T
Tom Ekberg

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

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)

如果它得到一个字符串,它需要特定的值,否则引发异常。如果它没有得到一个字符串,就让 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('')
N
Nomi

您还可以评估任何字符串文字:

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

N
Neuron

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

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

https://i.stack.imgur.com/r5Pje.png

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

distutils 是 python std lib 的一部分,所以不需要安装任何东西,这很棒! 👍


请注意, distutils 包自 python 3.10 起已弃用,并将在 3.12 版中删除。
就像生活中的其他一切一样,美好的事物走到了尽头:(
N
Neuron

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

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

您实际上不需要 if s else False 位。想想 "False" == "True" 将如何返回 False
如果您不确定输入 s 是字符串还是布尔值,您可以添加 if type(s) is bool: return s
A
Anand Tripathi

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

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

不能解决字符串可能为“0”的问题。 >>> type(ast.literal_eval("0".title())) <class 'int'>
R
Ron E

我意识到这是一篇旧文章,但有些解决方案需要相当多的代码,这就是我最终使用的:

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

这在功能上等同于,并且比: return value in ('True', 'true')
H
Headmaster

使用包 str2bool pip install str2bool


A
ARHAM RUMI

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

def string_to_bool(s):
    bool_flag = True
    if s == "False":
        bool_flag = False
    elif s == "True":
        bool_flag = True
    else:
        print("Invalid Input")
    return bool_flag

您还可以查看 TrueFalse 的更多缩写,例如 Y/Ny/n 等。


额外的 bool_flag 变量太没用了
@BlakBat 怎么样?你能解释为什么它没有用吗?
只需返回值:如果 s == "False":返回 False。等等
N
Neuron

使用此解决方案:

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

我喜欢这个,因为它是正确处理错误输入的唯一解决方案之一
R
RE_Specto

如果是这样,我们可能需要捕捉“真”不区分大小写:

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

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

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


您也可以只执行 x in 'True true',它要短得多。但仍然很糟糕,因为它接受 'ue tr' 作为 True...
@Neuron 好点。编辑。