从文件读取的True / False值转换为布尔值


86

我正在True - False从文件中读取一个值,我需要将其转换为布尔值。当前,True即使将值设置为,它也始终将其转换为False

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文件基本上由带有值TrueFalse写入其中的单个字符串组成。这种安排看起来很复杂,因为这是来自更大代码的最小示例,这也是我将参数读入其中的方式。

为什么flag总是转换为True


1
pip install str2bool
Symon

Answers:


100

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

引用伟人(和Python文档):

5.1。真值测试

可以测试任何对象的真值,以在if或while条件中使用或用作以下布尔运算的操作数。以下值为“假”:

  • 任何数值类型的零,例如00L0.00j
  • 任何空序列,例如''()[]

所有其他值都被认为是真实的-因此许多类型的对象总是真实的。

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

23
您可以ValueError通过这样做使它成为“英雄” raise ValueError("Cannot covert {} to a bool".format(s))
SethMMorton 2014年

选择此选项是因为它不使用任何额外的程序包。谢谢你们!
加百利

1
“额外包裹”有什么问题?你指的是ast什么?它是标准库的一部分,因此并不算多余。
SethMMorton 2014年

4
这可能是一个愚蠢的问题,但是为什么不bool将字符串TrueFalse布尔值转换为TrueFalse呢?似乎与int所做的行为不一致。我只是真的很好奇为什么我的推理是错误的,为什么另一个选择就是决定。
查理·帕克

1
每当比较字符串时,我都希望弄平大小写(如果适用)。例如,我将使用:if s.upper()=='TRUE':return True elif s.upper()=='FALSE'return False
比尔·基德


61

用途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)

这可能是一个愚蠢的问题,但是为什么不bool将字符串TrueFalse布尔值转换为TrueFalse呢?似乎与int所做的行为不一致。我只是真的很好奇为什么我的推理是错误的,为什么另一个选择就是决定。
查理·帕克

2
ast.literal_eval('false')引发异常,我认为这不太理想
Chris

@Chris您始终可以在自定义函数中将其包裹在try-except周围,而不是直接使用它。
Ashwini Chaudhary

@HewwoCraziness它仅解析表达式,而不解析任何随机代码。
Ashwini Chaudhary

15

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

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

当然,它需要导入,但是具有正确的错误处理,并且几乎不需要编写(和测试)代码。


13

我不建议将其作为最佳答案,而只是替代方法,但您也可以执行以下操作:

flag = reader[0] == "True"

标志将是Trueid reader [0]为“ True”,否则为False


10

当前,它正在评估,True因为变量具有值。这里有一个很好的例子,说明了当您将任意类型评估为布尔值时会发生什么。

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

>>> eval('True')
True
>>> eval('False')
False

4
@samyi使用eval方法很危险。stackoverflow.com/questions/1832940/...
M07

1
仅供参考。这是一个可怕的主意,您永远不要使用eval()。我认为应该将其从语言中删除。
Nostalg.io

这非常不好,因为它是安全缺陷。如果您使用eval()文件中的原始数据,则意味着对该文件具有写访问权的任何人都可以以与脚本相同的权限级别执行代码。
基思·里普利

另外,如果值没有精确的python拼写,例如eval('false')eval('FALSE')它将出错。
kev

5

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

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

5

如果您希望不区分大小写,则可以执行以下操作:

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

3

pip安装str2bool

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

2

您可以使用json

In [124]: import json

In [125]: json.loads('false')
Out[125]: False

In [126]: json.loads('true')
Out[126]: True

2

只需补充一下,如果您的真值可以变化,例如,它是来自不同编程语言或不同类型的输入,则更可靠的方法是:

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


0

如果您需要快速将字符串转换为bool的方法(大多数字符串都可以使用),请尝试。

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


0

使用字典将True转换为“ True”:

def str_to_bool(s: str):
    status = {"True": True,
                "False": False}
    try:
        return status[s]
    except KeyError as e:
        #logging
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.