Estoy leyendo un True - False
valor de un archivo y necesito convertirlo a booleano. Actualmente, siempre lo convierte True
incluso si el valor está establecido en False
.
Aquí está una MWE
de lo que estoy tratando de hacer:
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'
El file.dat
archivo consta básicamente de una sola cadena con el valor True
o False
escrito en su interior. El arreglo parece muy complicado porque este es un ejemplo mínimo de un código mucho más grande y así es como leo los parámetros en él.
¿Por qué flag
siempre se está convirtiendo a True
?
Respuestas:
bool('True')
ybool('False')
siempre regresaTrue
porque las cadenas 'True' y 'False' no están vacías.Para citar a un gran hombre (y documentación de Python ):
La
bool
función incorporada utiliza el procedimiento estándar de prueba de verdad. Es por eso que siempre estás recibiendoTrue
.Para convertir una cadena en booleano, debe hacer algo como esto:
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
fuente
ValueError
haciéndoloraise ValueError("Cannot covert {} to a bool".format(s))
.ast
? Es parte de la biblioteca estándar, por lo que no es realmente extra.bool
simplemente no convierte las cadenasTrue
yFalse
los valores booleanosTrue
yFalse
? Parece ser un comportamiento inconsistente de lo queint
hace. Tengo curiosidad genuina de por qué mi razonamiento es incorrecto y por qué la otra opción fue la decisión.puedes usar
distutils.util.strtobool
>>> from distutils.util import strtobool >>> strtobool('True') 1 >>> strtobool('False') 0
True
valores sony
,yes
,t
,true
,on
y1
;False
los valores sonn
,no
,f
,false
,off
y0
. SubeValueError
si val es otra cosa.fuente
bool(strtobool(my_string))
para convertir la salida como una variable booleana Verdadero / Falsostrtobool()
no, de hecho, devuelve unbool
Utilizar
ast.literal_eval
:>>> import ast >>> ast.literal_eval('True') True >>> ast.literal_eval('False') False
Las cadenas no vacías siempre son verdaderas en Python.
Relacionado: Prueba de valor de verdad
Si NumPy es una opción, entonces:
>>> 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)
fuente
bool
simplemente no convierte las cadenasTrue
yFalse
los valores booleanosTrue
yFalse
? Parece ser un comportamiento inconsistente de lo queint
hace. Tengo curiosidad genuina de por qué mi razonamiento es incorrecto y por qué la otra opción fue la decisión.La solución más limpia que he visto es:
from distutils.util import strtobool def string_to_bool(string): return bool(strtobool(str(string)))
Claro, requiere una importación, pero tiene un manejo adecuado de errores y requiere muy poco código para ser escrito (y probado).
fuente
No me sugiero que esta sea la mejor respuesta, solo una alternativa, pero también puede hacer algo como:
flag = reader[0] == "True"
la bandera será
True
id reader [0] es "True", de lo contrario lo seráFalse
.fuente
Actualmente, está evaluando a
True
porque la variable tiene un valor. Aquí se encuentra un buen ejemplo de lo que sucede cuando evalúa tipos arbitrarios como booleanos.En resumen, lo que quiere hacer es aislar la cadena
'True'
o'False'
y ejecutarlaeval
.>>> eval('True') True >>> eval('False') False
fuente
eval()
. En mi opinión, debería eliminarse del idioma.eval()
datos sin procesar de un archivo, significa que cualquier persona con acceso de escritura a ese archivo puede ejecutar código con el mismo nivel de permisos que su script.eval('false')
,eval('FALSE')
se producirá un error.Puede usar dict para convertir cadenas a booleanas. Cambie esta línea
flag = bool(reader[0])
a:flag = {'True': True, 'False': False}.get(reader[0], False) # default is False
fuente
Si desea distinguir entre mayúsculas y minúsculas, puede hacer lo siguiente:
b = True if bool_str.lower() == 'true' else False
Uso de ejemplo:
>>> 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
fuente
pip instalar str2bool
>>> from str2bool import str2bool >>> str2bool('Yes') True >>> str2bool('FaLsE') False
fuente
Puede hacer con
json
.In [124]: import json In [125]: json.loads('false') Out[125]: False In [126]: json.loads('true') Out[126]: True
fuente
Solo para agregar que si su valor de verdad puede variar, por ejemplo, si es una entrada de diferentes lenguajes de programación o de diferentes tipos, un método más robusto sería:
flag = value in ['True','true',1,'T','t','1'] # this can be as long as you want to support
Y una variante más eficaz sería (set lookup is O (1)):
TRUTHS = set(['True','true',1,'T','t','1']) flag = value in truths
fuente
Si sus datos son de json, puede hacerlo
fuente
Si necesita una forma rápida de convertir cadenas en bools (que funciona con la mayoría de las cadenas) intente.
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
fuente
Usar dictados para convertir "Verdadero" en Verdadero:
def str_to_bool(s: str): status = {"True": True, "False": False} try: return status[s] except KeyError as e: #logging
fuente