关于python:将从文件读取的True / False值转换为boolean

Convert True/False value read from file to boolean

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

以下是我想做的事情:

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


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

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

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


使用ast.literal_eval

1
2
3
4
5
>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False

Why is flag always converting to True?

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

相关:真值测试

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

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


您可以使用distutils.util.strtobool

1
2
3
4
5
6
>>> from distutils.util import strtobool

>>> strtobool('True')
1
>>> strtobool('False')
0

True值为yyestTrueon1False值为nnofFalseoff0。如果val为其他值,则提升ValueError


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

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

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


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

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

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


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

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

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


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

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

你可以使用json

1
2
3
4
5
6
7
In [124]: import json

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

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


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

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

示例用法:

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


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

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

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

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


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

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


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

import json

json.loads('true')

True


PIP安装str2bool

1
2
3
4
5
>>> from str2bool import str2bool
>>> str2bool('Yes')
True
>>> str2bool('FaLsE')
False