web-dev-qa-db-fra.com

Convertir la valeur True/False lue du fichier en booléen

Je lis une valeur True - False à partir d'un fichier et je dois le convertir en booléen. Actuellement, il le convertit toujours en True même si la valeur est définie sur False.

Voici une MWE de ce que j'essaie de faire:

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'

Le fichier file.dat consiste essentiellement en une seule chaîne avec la valeur True ou False écrite à l'intérieur. Cet arrangement semble très compliqué car il s’agit d’un exemple minimal tiré d’un code beaucoup plus volumineux et c’est ainsi que j’ai lu les paramètres.

Pourquoi flag est-il toujours converti en True?

65
Gabriel

bool('True') et bool('False') retournent toujours True car les chaînes "True" et "False" ne sont pas vides.

Pour citer un grand homme (et Python documentation ):

5.1. Test de valeur de vérité

Tout objet peut être testé pour la valeur de vérité, pour une utilisation dans un if ou un condition ou comme opérande des opérations booléennes ci-dessous. Le les valeurs suivantes sont considérées comme fausses:

  • zéro de tout type numérique, par exemple, 0, 0L, 0.0, 0j.
  • toute séquence vide, par exemple, '', (), [].

Toutes les autres valeurs sont considérées comme vraies - donc des objets de nombreux types sont toujours vrais.

La fonction bool intégrée utilise la procédure de test de vérité standard. C'est pourquoi vous obtenez toujours True.

Pour convertir une chaîne en booléen, vous devez faire quelque chose comme ceci:

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
73
Nigel Tufnel

Utilisez ast.literal_eval :

>>> import ast
>>> ast.literal_eval('True')
True
>>> ast.literal_eval('False')
False

Pourquoi flag convertit-il toujours en True?

Les chaînes non vides sont toujours vraies en Python.

Connexes: Test de valeur de vérité


Si NumPy est une option, alors:

>>> 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)
52
Ashwini Chaudhary

vous pouvez utiliser distutils.util.strtobool

>>> from distutils.util import strtobool

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

Les valeurs True sont y, yes, t, true, on et 1; Les valeurs False sont n, no, f, false, off et 0. Lève ValueError si val est autre chose.

46
Francesco Nazzaro

Je ne suggère pas cela comme la meilleure réponse, juste une alternative mais vous pouvez aussi faire quelque chose comme:

flag = reader[0] == "True"

flag sera True id reader [0] est "True", sinon ce sera False.

9
elParaguayo

La solution la plus propre que j'ai vue est:

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

Bien sûr, il nécessite une importation, mais sa gestion des erreurs est correcte et son écriture (et son test) très réduite.

7
vpetersson

Actuellement, il est évalué à True car la variable a une valeur. Voici un bon exemple trouvé ici de ce qui se passe lorsque vous évaluez des types arbitraires en tant que booléens.

En bref, vous voulez isoler la chaîne 'True' ou 'False' et exécuter eval dessus.

>>> eval('True')
True
>>> eval('False')
False
7
Gautam Joshi

Vous pouvez utiliser dict pour convertir une chaîne en booléen. Remplacez cette ligne flag = bool(reader[0]) par:

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

Si vous voulez être insensible à la casse, vous pouvez simplement faire:

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

Exemple d'utilisation:

>>> 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
caleb

Vous pouvez faire avec json

In [124]: import json

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

In [126]: json.loads('true')
Out[126]: True
1
Rahul K P

Si vous avez besoin d'un moyen rapide de convertir des chaînes en livres (cela fonctionne avec la plupart des chaînes), essayez.

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
user6830669

pip install str2bool

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

Juste pour ajouter que si votre valeur de vérité peut varier, par exemple s'il s'agit d'une entrée de différents langages de programmation ou de types différents, une méthode plus robuste serait:

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

Et une variante plus performante serait (la recherche d'ensemble est O (1)):

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

Si vos données proviennent de JSON, vous pouvez le faire.

importer json

json.loads ('true')

Vrai