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

2025-01-16 08:38:00
admin
原创
99
摘要:问题描述:如何在 Python 中将字符串转换为布尔值?此尝试返回True:>>> bool("False") True 解决方案 1:实际上,你只需将字符串与你期望接受的代表真实的内容进行比较,因此你可以这样做:s == 'True' 或者检查一大堆值:s.lower(...

问题描述:

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

>>> bool("False")
True

解决方案 1:

实际上,你只需将字符串与你期望接受的代表真实的内容进行比较,因此你可以这样做:

s == 'True'

或者检查一大堆值:

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

使用以下内容时请小心:

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

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

解决方案 2:

警告:从 Python 3.12 开始,此答案将不再有效(从 3.10 开始已被弃用)

使用:

bool(distutils.util.strtobool(some_string))
  • Python 2distutils.util.strtobool

  • Python> = 3,<3.12distutils.util.strtobool

  • Python >=3.12 : 由于PEP 632 – 弃用 distutils 模块,不再是标准库的一部分

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

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

鉴于 distutils 将不再是标准库的一部分,这里是代码distutils.util.strtobool()(参见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,))

解决方案 3:

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 列表。然后,如果它不在任何一个列表中,您可以抛出异常。

解决方案 4:

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

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

解决方案 5:

从Python 2.6开始您可以使用ast.literal_eval,并且它在Python 3中仍然可用。

评估仅包含 Python 文字或容器显示的表达式节点或字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值NoneEllipsis

这可用于评估包含 Python 值的字符串,而无需自己解析值。它无法评估任意复杂的表达式,例如涉及运算符或索引的表达式。

过去,该函数曾被记录为“安全”,但没有定义其含义。这是误导。与更通用的 不同,它专门设计用于不执行 Python 代码。eval()它没有命名空间、名称查找或调用能力。但它并非免受攻击:相对较小的输入可能会导致内存耗尽或 C 堆栈耗尽,从而使进程崩溃。某些输入还可能出现过度 CPU 消耗拒绝服务的情况。因此,不建议对不受信任的数据调用它

这似乎有效,只要你确定你的字符串将"True""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'

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

解决方案 6:

警告:除非您确实知道要用以下代码做什么,否则请不要使用它们。请阅读随附的免责声明,并确保您信任您的输入,因为在不受信任的输入上使用此代码可能会破坏您的数据和/或让您丢掉工作。

如果您知道字符串是"True""False",那么您可以直接使用eval(s)

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

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

解决方案 7:

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

为了pydantic >=2

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

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

为了pydantic <2

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

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

解决方案 8:

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

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

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


我想分享我的简单解决方案:使用。如果字符串完全符合标题格式或始终首字母大写eval(),它将把字符串转换为正确的布尔类型,否则该函数将引发错误。True`FalseTrueFalse`

例如

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

解决方案 9:

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

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

解决方案 10:

你可以做类似的事情

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

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

解决方案 11:

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

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

解决方案 12:

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

import yaml

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

如果范围太广,可以通过测试类型结果来改进。如果 yaml 返回的类型是 str,则无法将其转换为任何其他类型(无论如何我能想到的),因此您可以单独处理它,或者让它为真。

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

解决方案 13:

字典(实际上是默认字典)可以给你一个非常简单的方法来实现这个技巧:

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

如果你想聪明一点,你可以用以下方法缩短它:itertools

from itertools import chain, repeat

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

这可能很蠢,但是itertools这些技巧还是挺有趣的。

解决方案 14:

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

以下是我使用的解决方案:

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)

结果如下:

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

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

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

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

解决方案 15:

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

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

如果a == 'true'那么这将设置a=True,如果a == 'false'那么a=False

解决方案 16:

另一种选择

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

解决方案 17:

我用

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

解决方案 18:

您可能已经有了解决方案,但对于其他人来说,他们正在寻找一种将值转换为布尔值的方法,除了 false、no 和 0 之外,还使用“标准”错误值(包括 None、[]、{} 和 "")。

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

解决方案 19:

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

boolean_response = bool(int(response))

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

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

解决方案 20:

如果您像我一样,只需要字符串变量中的布尔值。您可以按照@jzwiener 所述使用 distils 。但是我无法按照他的建议导入和使用该模块。

相反,我最终在 python3.7 上这样使用它

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

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

distutils 是 python std lib 的一部分,因此无需安装任何东西,这很棒!

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用