web-dev-qa-db-fra.com

Conversion d'une chaîne en booléen en Python?

Est-ce que quelqu'un sait comment convertir une chaîne en un booléen en Python? J'ai trouvé ce lien . Mais cela ne semble pas être une bonne façon de le faire. C'est à dire. en utilisant une fonctionnalité intégrée, etc.

MODIFIER:

La raison pour laquelle j'ai demandé cela est parce que j'ai appris int("string"), à partir d'ici. J'ai essayé bool("string") mais ai toujours eu True.

>>> bool("False")
True
545
Joan Venge

Vraiment, vous comparez simplement la chaîne à ce que vous vous attendez à accepter comme représentant la valeur true, vous pouvez donc effectuer ceci:

s == 'True'

Ou pour vérifier contre tout un tas de valeurs:

s in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh']

Soyez prudent lorsque vous utilisez ce qui suit:

>>> bool("foo")
True
>>> bool("")
False

Les chaînes vides sont évaluées à False, mais tout le reste est évalué à True. Cela ne devrait donc pas être utilisé à des fins d'analyse syntaxique.

643
Keith Gaughan
def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

Alors appelle ça comme ça:

str2bool("yes")

> True

str2bool("no")

> False

str2bool("stuff")

> False

str2bool("1")

> True

str2bool("0")

> False


Gestion du vrai et du faux explicitement:

Vous pouvez également faire vérifier explicitement votre fonction par rapport à une liste de mots vraie et à une liste de mots faux. Ensuite, si elle ne figure dans aucune des deux listes, vous pouvez générer une exception. 

221
Brian R. Bondy

Il suffit d'utiliser:

distutils.util.strtobool(some_string)

http://docs.python.org/2/distutils/apiref.html?highlight=distutils.util#distutils.util.strtobool

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

200
jzwiener

Depuis Python 2.6, il existe maintenant ast.literal_eval:

 >>> import ast 
 >>> help (ast.literal_eval) 
 Aide sur la fonction literal_eval dans le module ast: 

 literal_eval (node_or_string) 
 Évaluez en toute sécurité un nœud d'expression ou une chaîne contenant un fichier Python 
 expression. La chaîne ou le noeud fourni ne peut être constitué que de ce qui suit 
 Structures littérales en python: chaînes, nombres, n-uplets, listes, dicts, booléens, 
 et Aucun .

Ce qui semble fonctionner, tant que vous êtes certain que vos chaînes vont être soit "True", soit "False":

 >>> ast.literal_eval ("True") 
 True 
 >>> ast.literal_eval ("False") 
 False 
 >>> ast.literal_eval ("F") 
 Traceback (dernier appel passé): 
 Fichier "", ligne 1, dans 
 Fichier "/opt/Python-2.6.1/lib/python2.6/ast.py", ligne 68, dans literal_eval 
 return _convert (node_or_string) 
 Fichier "/opt/Python-2.6.1/lib/python2.6/ast.py", ligne 67, dans _convert 
 raise ValueError ('chaîne malformée') 
 ValueError: chaîne malformée 
 >>> ast.literal_eval ("'False'") 
 'False' 

Je ne recommanderais normalement pas ceci, mais il est complètement intégré et pourrait être la bonne chose en fonction de vos besoins.

101
Jacob Gabrielson

L'analyseur JSON est également utile pour convertir en général des chaînes en types python raisonnables.

>>> import json
>>> json.loads("false".lower())
False
>>> json.loads("True".lower())
True
80
Alan Marchiori

Cette version conserve la sémantique des constructeurs comme int (valeur) et fournit un moyen simple de définir des valeurs de chaîne acceptables.

def to_bool(value):
    valid = {'true': True, 't': True, '1': True,
             'false': False, 'f': False, '0': False,
             }   

    if isinstance(value, bool):
        return value

    if not isinstance(value, basestring):
        raise ValueError('invalid literal for boolean. Not a string.')

    lower_value = value.lower()
    if lower_value in valid:
        return valid[lower_value]
    else:
        raise ValueError('invalid literal for boolean: "%s"' % value)


# Test cases
assert to_bool('true'), '"true" is True' 
assert to_bool('True'), '"True" is True' 
assert to_bool('TRue'), '"TRue" is True' 
assert to_bool('TRUE'), '"TRUE" is True' 
assert to_bool('T'), '"T" is True' 
assert to_bool('t'), '"t" is True' 
assert to_bool('1'), '"1" is True' 
assert to_bool(True), 'True is True' 
assert to_bool(u'true'), 'unicode "true" is True'

assert to_bool('false') is False, '"false" is False' 
assert to_bool('False') is False, '"False" is False' 
assert to_bool('FAlse') is False, '"FAlse" is False' 
assert to_bool('FALSE') is False, '"FALSE" is False' 
assert to_bool('F') is False, '"F" is False' 
assert to_bool('f') is False, '"f" is False' 
assert to_bool('0') is False, '"0" is False' 
assert to_bool(False) is False, 'False is False'
assert to_bool(u'false') is False, 'unicode "false" is False'

# Expect ValueError to be raised for invalid parameter...
try:
    to_bool('')
    to_bool(12)
    to_bool([])
    to_bool('yes')
    to_bool('FOObar')
except ValueError, e:
    pass
14
Michael Richmond

Voici ma version. Il vérifie à la fois les listes de valeurs positives et négatives, générant une exception pour les valeurs inconnues. Et il ne reçoit pas de chaîne, mais tout type devrait faire l'affaire.

def to_bool(value):
    """
       Converts 'something' to boolean. Raises exception for invalid formats
           Possible True  values: 1, True, "1", "TRue", "yes", "y", "t"
           Possible False values: 0, False, None, [], {}, "", "0", "faLse", "no", "n", "f", 0.0, ...
    """
    if str(value).lower() in ("yes", "y", "true",  "t", "1"): return True
    if str(value).lower() in ("no",  "n", "false", "f", "0", "0.0", "", "none", "[]", "{}"): return False
    raise Exception('Invalid value for boolean conversion: ' + str(value))

Échantillons:

>>> to_bool(True)
True
>>> to_bool("tRUe")
True
>>> to_bool("1")
True
>>> to_bool(1)
True
>>> to_bool(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: 2
>>> to_bool([])
False
>>> to_bool({})
False
>>> to_bool(None)
False
>>> to_bool("Wasssaaaaa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in to_bool
Exception: Invalid value for boolean conversion: Wasssaaaaa
>>>
12
Petrucio

Si vous savez que la chaîne sera soit "True" ou "False", vous pouvez simplement utiliser eval(s).

>>> eval("True")
True
>>> eval("False")
False

Utilisez-le uniquement si vous êtes sûr du contenu de la chaîne, car il lève une exception si la chaîne ne contient pas de code Python valide et exécute également le code contenu dans la chaîne.

10
Joel Croteau

vous pouvez toujours faire quelque chose comme 

myString = "false"
val = (myString == "true")

le bit en parens serait évalué à False. Ceci est juste une autre façon de le faire sans avoir à faire un appel de fonction réel.

9
helloandre

Vous pouvez simplement utiliser la fonction intégrée eval () :

a='True'
if a is True:
    print 'a is True, a type is', type(a)
else:
    print "a isn't True, a type is", type(a)
b = eval(a)
if b is True:
    print 'b is True, b type is', type(b)
else:
    print "b isn't True, b type is", type(b)

et la sortie:

a isn't True, a type is <type 'str'>
b is True, b type is <type 'bool'>
8
lumartor

Je ne suis d'accord avec aucune solution ici, car elles sont trop permissives. Ce n'est normalement pas ce que vous voulez lors de l'analyse d'une chaîne.

Alors voici la solution que j'utilise:

def to_bool(bool_str):
    """Parse the string and return the boolean value encoded or raise an exception"""
    if isinstance(bool_str, basestring) and bool_str: 
        if bool_str.lower() in ['true', 't', '1']: return True
        Elif bool_str.lower() in ['false', 'f', '0']: return False

    #if here we couldn't parse it
    raise ValueError("%s is no recognized as a boolean value" % bool_str)

Et les résultats:

>>> [to_bool(v) for v in ['true','t','1','F','FALSE','0']]
[True, True, True, False, False, False]
>>> to_bool("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in to_bool
ValueError: '' is no recognized as a boolean value

Soyons clairs, car il semblerait que ma réponse ait offensé quelqu'un:

Le fait est que vous ne voulez pas tester uniquement une valeur et assumer l’autre. Je ne pense pas que vous vouliez toujours mapper absolument tout à la valeur non analysée. Cela produit du code sujet aux erreurs.

Donc, si vous savez ce que vous voulez coder.

7
estani

Un truc simple et cool (basé sur ce que @ Alan Marchiori a posté), mais en utilisant yaml:

import yaml

parsed = yaml.load("true")
print bool(parsed)

Si celle-ci est trop large, vous pouvez l'affiner en testant le résultat du type. Si le type retourné par yaml est un str, il ne peut pas être converti en un autre type (auquel je peux penser de toute façon), vous pouvez donc le gérer séparément ou simplement le laisser vrai.

Je ne devinerai pas rapidement, mais comme je travaille avec des données yaml sous Qt gui de toute façon, cela a une symétrie de Nice.

6
Rafe

Un dict (en réalité, un defaultdict) vous donne un moyen assez facile de faire cette astuce:

from collections import defaultdict
bool_mapping = defaultdict(bool) # Will give you False for non-found values
for val in ['True', 'yes', ...]:
    bool_mapping[val] = True

print(bool_mapping['True']) # True
print(bool_mapping['kitten']) # False

Il est très facile d'adapter cette méthode au comportement de conversion exact que vous souhaitez - vous pouvez la remplir avec les valeurs autorisées de Truthy et Falsy et la laisser lever une exception (ou renvoyer Aucune) lorsqu'une valeur n'est pas trouvée, ou par défaut à True ou par défaut à False, ou ce que vous voulez.

5
Nate

Vous avez probablement déjà une solution, mais pour les autres qui recherchent une méthode pour convertir une valeur en valeur booléenne en utilisant des valeurs "standard", telles que Aucune, [], {} et "", ainsi que false, non et 0 .

def toBoolean( val ):
    """ 
    Get the boolean value of the provided input.

        If the value is a boolean return the value.
        Otherwise check to see if the value is in 
        ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]
        and returns True if value is not in the list
    """

    if val is True or val is False:
        return val

    falseItems = ["false", "f", "no", "n", "none", "0", "[]", "{}", "" ]

    return not str( val ).strip().lower() in falseItems
5
Chris McMillan

Je réalise que ceci est un ancien post, mais certaines solutions nécessitent un peu de code, voici ce que j'ai fini par utiliser:

def str2bool(value):
    return {"True": True, "true": True}.get(value, False)
3
Ron E

Ceci est la version que j'ai écrite. Combine plusieurs des autres solutions en une seule.

def to_bool(value):
    """
    Converts 'something' to boolean. Raises exception if it gets a string it doesn't handle.
    Case is ignored for strings. These string values are handled:
      True: 'True', "1", "TRue", "yes", "y", "t"
      False: "", "0", "faLse", "no", "n", "f"
    Non-string values are passed to bool.
    """
    if type(value) == type(''):
        if value.lower() in ("yes", "y", "true",  "t", "1"):
            return True
        if value.lower() in ("no",  "n", "false", "f", "0", ""):
            return False
        raise Exception('Invalid value for boolean conversion: ' + value)
    return bool(value)

S'il obtient une chaîne, il attend des valeurs spécifiques, sinon déclenche une exception. S'il ne reçoit pas de chaîne, laissez simplement le constructeur bool le résoudre. Testé ces cas:

test_cases = [
    ('true', True),
    ('t', True),
    ('yes', True),
    ('y', True),
    ('1', True),
    ('false', False),
    ('f', False),
    ('no', False),
    ('n', False),
    ('0', False),
    ('', False),
    (1, True),
    (0, False),
    (1.0, True),
    (0.0, False),
    ([], False),
    ({}, False),
    ((), False),
    ([1], True),
    ({1:2}, True),
    ((1,), True),
    (None, False),
    (object(), True),
    ]
3
Tom Ekberg

La règle habituelle pour la conversion en bool est que quelques littéraux spéciaux (False, 0, 0.0, (), [], {}) sont faux et que tout le reste est vrai. Je recommande ce qui suit:

def boolify(val):
    if (isinstance(val, basestring) and bool(val)):
        return not val in ('False', '0', '0.0')
    else:
        return bool(val)
3
Carl G

J'aime utiliser l'opérateur ternaire pour cela, car c'est un peu plus succinct pour quelque chose qui semble ne pas comporter plus d'une ligne.

True if myString=="True" else False
2
Clayton Rabenda

Si vous savez que votre entrée sera "True" ou "False", alors pourquoi ne pas utiliser:

def bool_convert(s):
    return s == "True"
2
Daniel van Flymen

Encore une autre option

from ansible.module_utils.parsing.convert_bool import boolean
boolean('no')
# False
boolean('yEs')
# True
boolean('true')
# True

Mais en production, si vous n'avez pas besoin de ansible et de toutes ses dépendances, il convient d'examiner son code source et de copier une partie de la logique dont vous avez besoin: https://github.com/ansible/ansible/blob/2bd6b1415b9131c3a7cb13724f5d31bb0d33846b /lib/ansible/module_utils/parsing/convert_bool.py

1
Maciej Kucia

Je devais juste faire ça ... alors peut-être tard pour la fête - mais quelqu'un pourrait le trouver utile

def str_to_bool(input, default):
    """
    | Default | not_default_str | input   | result
    | T       |  "false"        | "true"  |  T
    | T       |  "false"        | "false" |  F
    | F       |  "true"         | "true"  |  T
    | F       |  "true"         | "false" |  F

    """
    if default:
        not_default_str = "false"
    else:
        not_default_str = "true"

    if input.lower() == not_default_str:
        return not default
    else:
        return default
0
Rcynic

Si vous m'aimez juste besoin de boolean de variable qui est string. Vous pouvez utiliser les distils mentionnés précédemment par @jzwiener. Cependant, je ne pouvais pas importer et utiliser le module comme il l'avait suggéré.

Au lieu de cela, je finis par l'utiliser de cette façon sur python3.7

distutils string to bool in python

from distutils import util # to handle str to bool conversion
enable_deletion = 'False'
enable_deletion = bool(util.strtobool(enable_deletion))

distutils fait partie de la librairie python std donc pas besoin d'installation. Ce qui est génial! ????

0
Gunay Anach

voici un poilu, construit de manière à obtenir plusieurs des mêmes réponses. Notez que bien que python considère que "" soit false et que toutes les autres chaînes soient vraies, TCL a une idée très différente des choses. 

>>> import Tkinter
>>> tk = Tkinter.Tk()
>>> var = Tkinter.BooleanVar(tk)
>>> var.set("false")
>>> var.get()
False
>>> var.set("1")
>>> var.get()
True
>>> var.set("[exec 'rm -r /']")
>>> var.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 324, in get
    return self._tk.getboolean(self._tk.globalgetvar(self._name))
_tkinter.TclError: 0expected boolean value but got "[exec 'rm -r /']"
>>> 

Une bonne chose à ce sujet est qu’il est assez indulgent quant aux valeurs que vous pouvez utiliser. Il est paresseux de transformer des chaînes en valeurs, et d'hygiène sur ce qu'il accepte et rejette (notez que si la déclaration ci-dessus était donnée à l'invite tcl, elle effacerait le disque dur de l'utilisateur). 

le problème, c'est que Tkinter doit être disponible, ce qui est généralement, mais pas toujours vrai, et plus important encore, la création d'une instance de Tk, relativement lourde. 

Ce qui est considéré comme vrai ou faux dépend du comportement du Tcl_GetBoolean, qui considère que0,false,noetoffest faux et1,true,yesetonpour être vrai, insensible à la casse. Toute autre chaîne, y compris la chaîne vide, provoque une exception.

def str2bool(str):
  if isinstance(str, basestring) and str.lower() in ['0','false','no']:
    return False
  else:
    return bool(str)

idée: cochez si vous voulez que la chaîne soit évaluée à False; sinon, bool () renvoie True pour toute chaîne non vide.

0
xvga

Utilisez le paquet str2boolpip install str2bool

0
Headmaster

Voici quelque chose que j'ai jeté ensemble pour évaluer la véracité d'une chaîne:

def as_bool(val):
 if val:
  try:
   if not int(val): val=False
  except: pass
  try:
   if val.lower()=="false": val=False
  except: pass
 return bool(val)

plus ou moins les mêmes résultats que si vous utilisiez eval mais plus sûr.

0
tylerl

Je viens de trouver cette solution simple lors de la recherche de l'opérateur ternaire dans Python:

(False, True)[val == "true"]

Cela fonctionne car dans Python True = 1 et False = 0 et une fois la comparaison évaluée, le résultat est utilisé pour obtenir l'élément du tuple par son index 0 ou 1. Un inconvénient est qu'il retournera False pour autre chose que "true", mais cela fonctionne bien pour mon scénario d'analyse de variable d'environnement.

0
Péter Veres