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

Converting from a string to boolean in Python?

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

编辑:

我之所以问这个是因为我从这里学了int("string")。我试过bool("string"),但总是得到True

1
2
>>> bool("False")
True


实际上,您只需将字符串与希望接受的表示"真"的内容进行比较,这样就可以做到:

1
s == 'True'

或者根据一系列的值进行检查:

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

使用以下各项时要小心:

1
2
3
4
>>> bool("foo")
True
>>> bool("")
False

空字符串的值为False,但其他值均为True。因此,这不应该用于任何类型的解析目的。


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

然后这样称呼它:

1
str2bool("yes")

> True

1
str2bool("no")

> False

1
str2bool("stuff")

> False

1
str2bool("1")

> True

1
str2bool("0")

> False

显式处理真假:

您还可以使您的函数显式地对照单词的真列表和单词的假列表进行检查。如果它不在这两个列表中,您可以抛出异常。


只需使用:

1
distutils.util.strtobool(some_string)

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

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.


从python 2.6开始,现在有了ast.literal_eval

1
2
3
4
5
6
7
8
9
>>> 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",这似乎是可行的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> 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'

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


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

1
2
3
4
5
>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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


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

1
2
3
4
>>> eval("True")
True
>>> eval("False")
False

但是,只有在您确定了字符串的内容时才使用此方法,因为如果字符串不包含有效的python,它将引发异常,并且还将执行字符串中包含的代码。


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

1
2
3
4
5
6
7
8
9
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))

样品运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> 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
>>>


你总是可以做一些像

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

parens中的位的值将为false。这只是另一种不用进行实际函数调用的方法。


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

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

1
2
3
4
5
6
7
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)

结果是:

1
2
3
4
5
6
7
>>> [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

只是说清楚,因为我的回答似乎冒犯了某人:

关键是,您不希望只测试一个值并假定另一个值。我认为您并不总是希望将所有内容都映射到未解析的值。这会产生容易出错的代码。

所以,如果你知道你想用什么编码。


您只需使用内置函数eval():

1
2
3
4
5
6
7
8
9
10
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)

输出:

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


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

1
2
3
4
import yaml

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

如果这太宽,可以通过测试类型结果来改进。如果yaml返回的类型是str,那么它不能强制转换为任何其他类型(无论如何我都能想到),所以您可以单独处理它,或者只允许它是真的。

我不会快速做出任何猜测,但由于我在qtgui下处理yaml数据,所以这有一个很好的对称性。


听写(实际上是默认听写)为您提供了一种非常简单的方法来执行此技巧:

1
2
3
4
5
6
7
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

将这个方法调整为您想要的精确转换行为真的很容易——您可以用允许的真实值和错误值填充它,并让它在找不到值、默认为真、默认为假或您想要的任何值时引发异常(或不返回任何值)。


您可能已经有了一个解决方案,但对于其他正在寻找方法将值转换为布尔值的人来说,除了使用"false"、"no"和"0",还使用"standard"假值,包括none、[]、和"none"。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
2
3
4
5
6
7
from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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构造函数来计算它。测试这些案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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),
    ]


我知道这是一篇老文章,但有些解决方案需要相当多的代码,下面是我最终使用的代码:

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


通常的规则是,一些特殊的文字(False00.0()[]{}是错误的,其他的都是正确的,所以我建议如下:

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

如果您知道您的输入将是"真"或"假",那么为什么不使用:

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


我喜欢使用三元运算符,因为它对于感觉不应该超过一行的内容更简洁。

1
True if myString=="True" else False


我只能这样做…所以参加派对可能会晚一点,但有人会觉得这很有用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

如果您对返回true/false的实体拥有控制权,一种选择是让它返回1/0,而不是返回true/false,那么:

boolean_response = bool(int(response))

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


这里有一个毛茸茸的,内置的方法来获得许多相同的答案。注意,尽管python认为""是假的,所有其他字符串都是真的,但tcl对事物的看法却截然不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> 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是真的,不区分大小写。任何其他字符串(包括空字符串)都会导致异常。


以下是我对一根弦的真实性的评估:

1
2
3
4
5
6
7
8
9
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的结果相同,但更安全。


使用包str2bool pip install str2bool


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

想法:检查是否要将字符串计算为false;否则,对于任何非空字符串,bool()都返回true。


通过使用python的内置eval()函数和.capitalize()方法,可以将任何"true"/"false"字符串(不考虑初始大小写)转换为真正的python布尔值。

例如:

1
2
3
4
5
6
7
8
9
true_false ="trUE"
type(true_false)

# OUTPUT: <type 'str'>

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

# OUTPUT: <type 'bool'>