我正在从文件中读取True - False
值,我需要将其转换为布尔值。目前,即使该值设置为 False
,它始终将其转换为 True
。
以下是我正在尝试执行的操作MWE
:
with 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
?
bool('True')
和bool('False')
总是返回True
,因为字符串"True"和"False"不为空。
引用一位伟人(和 Python 文档):
5.1. 真值测试
可以测试任何对象的真值,以便在 if 或 while 中使用 条件或作为下面布尔运算的操作数。这 以下值被视为 false:
- 。
- 任何数值类型的零,例如
0
、0L
、0.0
、0j
。- 任何空序列,例如
''
、()
、[]
。- 。
所有其他值都被视为 true,因此许多类型的对象 总是正确的。
内置bool
函数使用标准真值检验过程。这就是为什么你总是True
.
要将字符串转换为布尔值,您需要执行以下操作:
def 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
您可以使用distutils.util.strtobool
>>> 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
。
使用 ast.literal_eval
:
>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False
为什么标志总是转换为 True?
非空字符串在 Python 中始终为 True。
相关:真值测试
如果 NumPy 是一个选项,那么:
>>> 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)
我见过的最干净的解决方案是:
from distutils.util import strtobool
def string_to_bool(string):
return bool(strtobool(str(string)))
当然,它需要导入,但它具有适当的错误处理,并且需要编写(和测试)的代码很少。
建议将此作为最佳答案,只是一种替代方案,但您也可以执行以下操作:
flag = reader[0] == "True"
标志将为True
id reader[0] 为"True",否则将False
。
目前,它正在计算True
,因为变量有一个值。这里有一个很好的例子,说明当您将任意类型评估为布尔值时会发生什么。
简而言之,您要做的是隔离'True'
或'False'
字符串并在其上运行eval
。
>>> eval('True')
True
>>> eval('False')
False
如果你想不区分大小写,你可以做:
b = True if bool_str.lower() == 'true' else False
用法示例:
>>> 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
您可以使用 dict 将字符串转换为布尔值。将此行flag = bool(reader[0])
更改为:
flag = {'True': True, 'False': False}.get(reader[0], False) # default is False
用json
.
In [124]: import json
In [125]: json.loads('false')
Out[125]: False
In [126]: json.loads('true')
Out[126]: True
pip install str2bool
>>> from str2bool import str2bool
>>> str2bool('Yes')
True
>>> str2bool('FaLsE')
False
如果你的数据来自json,你可以这样做
导入 JSON
json.loads('true')
真
补充一点,如果你的真值可以变化,例如,如果它是来自不同编程语言或不同类型的输入,一个更健壮的方法是:
flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support
一个性能更高的变体是(设置查找是 O(1)):
TRUTHS = set(['True','true',1,'T','t','1'])
flag = value in truths
不幸的是,strtobool
现在已被弃用。
这是一个基于配置解析器的实现,您可以使用它代替bool
:
import configparser
def strtobool(s):
try:
return configparser.ConfigParser.BOOLEAN_STATES[s.lower()]
except KeyError as e:
raise ValueError('Not a boolean: %s' % s) from e
如果您需要快速将字符串转换为布尔值(适用于大多数字符串),请尝试。
def 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
使用字典将"True"转换为 True:
def str_to_bool(s: str):
status = {"True": True,
"False": False}
try:
return status[s]
except KeyError as e:
#logging
如果你有
>>> my_value = "False"
然后要么做
>>> my_value in "False"
True
>>> my_value in "True"
False
或
>>> "False" in my_value
True
>>> "True" in my_value
False
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 True
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return False
else:
raise ValueError("invalid truth value %r" % (val,))
三元运算符单行:
var_x = True if str_x == 'True' else False