Estoy leyendo un True - Falsevalor de un archivo y necesito convertirlo a booleano. Actualmente, siempre lo convierte Trueincluso si el valor está establecido en False.
Aquí está una MWEde 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.datarchivo consta básicamente de una sola cadena con el valor Trueo Falseescrito 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é flagsiempre se está convirtiendo a True?

Respuestas:
bool('True')ybool('False')siempre regresaTrueporque las cadenas 'True' y 'False' no están vacías.Para citar a un gran hombre (y documentación de Python ):
La
boolfunció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 wasfuente
ValueErrorhaciéndoloraise ValueError("Cannot covert {} to a bool".format(s)).ast? Es parte de la biblioteca estándar, por lo que no es realmente extra.boolsimplemente no convierte las cadenasTrueyFalselos valores booleanosTrueyFalse? Parece ser un comportamiento inconsistente de lo queinthace. 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') 0Truevalores sony,yes,t,true,ony1;Falselos valores sonn,no,f,false,offy0. SubeValueErrorsi val es otra cosa.fuente
bool(strtobool(my_string))para convertir la salida como una variable booleana Verdadero / Falsostrtobool()no, de hecho, devuelve unboolUtilizar
ast.literal_eval:>>> import ast >>> ast.literal_eval('True') True >>> ast.literal_eval('False') FalseLas 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
boolsimplemente no convierte las cadenasTrueyFalselos valores booleanosTrueyFalse? Parece ser un comportamiento inconsistente de lo queinthace. 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á
Trueid reader [0] es "True", de lo contrario lo seráFalse.fuente
Actualmente, está evaluando a
Trueporque 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') Falsefuente
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 Falsefuente
Si desea distinguir entre mayúsculas y minúsculas, puede hacer lo siguiente:
b = True if bool_str.lower() == 'true' else FalseUso 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 Truefuente
pip instalar str2bool
>>> from str2bool import str2bool >>> str2bool('Yes') True >>> str2bool('FaLsE') Falsefuente
Puede hacer con
json.In [124]: import json In [125]: json.loads('false') Out[125]: False In [126]: json.loads('true') Out[126]: Truefuente
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 supportY una variante más eficaz sería (set lookup is O (1)):
TRUTHS = set(['True','true',1,'T','t','1']) flag = value in truthsfuente
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 falsefuente
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: #loggingfuente