我正在从文件中读取True - False值,需要将其转换为布尔值。目前,它总是将其转换为True,即使该值设置为False。

以下是我想做的事情:


10with open('file.dat', mode="r") as f:
for line in f:
reader = line.split()
# Convert to boolean <-- Not working?
flag = bool(reader[0])
if flag:
print 'flag == True'
else:
print 'flag == False'

file.dat文件基本上由单个字符串组成,其中写入值True或False。这种安排看起来非常复杂,因为这是一个非常大的代码的最小示例,这就是我如何将参数读取到其中。

为什么flag总是转换成True?

PIP install str2bool

bool('True')和bool('False')总是返回True,因为字符串'true'和'false'不是空的。

引用一个伟人(和python文档):

5.1. Truth Value Testing

Any object can be tested for truth value, for use in an if or while
condition or as operand of the Boolean operations below. The
following values are considered false:
…
zero of any numeric type, for example, 0, 0L, 0.0, 0j.
any empty sequence, for example, '', (), [].
…
All other values are considered true — so objects of many types
are always true.

内置的bool函数使用标准的真值测试过程。这就是为什么你总是得到True。

要将字符串转换为布尔值,需要执行以下操作:


7def str_to_bool(s):
if s == 'True':
return True
elif s == 'False':
return False
else:
raise ValueError # evil ValueError that doesn't tell you what the wrong value was

你可以通过做raise ValueError("Cannot covert {} to a bool".format(s))把它变成"英雄"ValueError。

选择这个,因为它不使用额外的包。谢谢你们!

"额外包裹"有什么问题?你是指ast吗?它是标准库的一部分,所以不是额外的。

这可能是一个愚蠢的问题,但为什么bool不把字符串True和False转换为布尔值True和False?似乎与int所做的行为不一致。我只是好奇为什么我的推理是错误的,为什么另一个选择是决定。

每当比较字符串时,我都喜欢将大小写变平(如果适用)。例如,我将使用:if s.upper()=="true":返回true elif s.upper()=="false"返回false

使用ast.literal_eval:


5>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False
号
Why is flag always converting to True?
号

在Python中,非空字符串总是正确的。

相关:真值测试

如果numpy是一个选项,那么:


6>>> import StringIO
>>> import numpy as np
>>> s = 'True - False - True'
>>> c = StringIO.StringIO(s)
>>> np.genfromtxt(c, delimiter='-', autostrip=True, dtype=None) #or dtype=bool
array([ True, False, True], dtype=bool)

这可能是一个愚蠢的问题,但为什么bool不把字符串True和False转换为布尔值True和False?似乎与int所做的行为不一致。我只是好奇为什么我的推理是错误的,为什么另一个选择是决定。

ast.literal_eval("false")引发了一个异常,我认为这会降低它的可取性。

@克里斯,除了在自定义函数中,你可以将它包装起来,而不是直接使用它。

您可以使用distutils.util.strtobool。


6>>> from distutils.util import strtobool
>>> strtobool('True')
1
>>> strtobool('False')
0
。

True值为y、yes、t、True、on和1;False值为n、no、f、False、off和0。如果val为其他值,则提升ValueError。

更好的是,bool(strtobool(my_string))是否将输出转换为布尔真/假变量

我不建议这是最好的答案,只是一个选择,但你也可以做如下的事情:

1flag = reader[0] =="True"
。

标志将是TrueID读卡器[0]为"真",否则将是False。

我见过最干净的解决方案是:


3from distutils.util import strtobool
def string_to_bool(string):
return bool(strtobool(str(string)))

当然,它需要导入,但是它有适当的错误处理,并且只需要编写(和测试)很少的代码。

目前,它正在对True进行评估,因为变量有一个值。这里有一个很好的例子,说明将任意类型作为布尔值进行计算时会发生什么。

简而言之,您要做的是隔离'True'或'False'字符串并在其上运行eval。


4>>> eval('True')
True
>>> eval('False')
False
。

@samyi使用eval方法很危险。stackoverflow.com/questions/1832940/&hellip;

FYI。这是一个可怕的想法,你不应该使用eval()。在我看来,它应该从语言中删除。

这是非常糟糕的,因为它是一个安全缺陷。如果对文件中的原始数据使用eval(),则意味着任何具有该文件写入权限的人都可以以与脚本相同的权限级别执行代码。

此外,如果值没有准确的python拼写,例如eval('false')、eval('false'),则会出错。

可以使用dict将字符串转换为布尔值。将该行flag = bool(reader[0])改为:

1flag = {'True': True, 'False': False}.get(reader[0], False) # default is False

你可以使用json。


7In [124]: import json
In [125]: json.loads('false')
Out[125]: False
In [126]: json.loads('true')
Out[126]: True

如果你想不区分大小写,你可以这样做:

1b = True if bool_str.lower() == 'true' else False

示例用法:


8>>> bool_str = 'False'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
False
>>> bool_str = 'true'
>>> b = True if bool_str.lower() == 'true' else False
>>> b
True

另外,如果您的真值可以改变,例如,如果它是来自不同编程语言或不同类型的输入,那么更健壮的方法是:

1flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support

更具性能的变体是(集合查找为O(1)):


2TRUTHS = set(['True','true',1,'T','t','1'])
flag = value in truths

如果您需要快速的方法将字符串转换为bool(大多数字符串都是这样的函数),请尝试。


6def conv2bool(arg):
try:
res= (arg[0].upper()) =="T"
except Exception,e:
res= False
return res # or do some more processing with arg if res is false

如果您的数据来自JSON,您可以这样做。

import json
json.loads('true')
True

PIP安装str2bool


5>>> from str2bool import str2bool
>>> str2bool('Yes')
True
>>> str2bool('FaLsE')
False