web-dev-qa-db-fra.com

Comment convertir "false" en 0 et "true" en 1 dans python

Y a-t-il un moyen de convertir true de type unicode en 1 et false de type unicode en 0 (en python)?

Par exemple: x == 'true' and type(x) == unicode

Je veux x = 1

PS: Je ne veux pas utiliser if-else.

86
PythonEnthusiast

Utilisez int() sur un test booléen:

x = int(x == 'true')

int() transforme le booléen en 1 ou 0. Notez que toute valeur not égale à 'true' aura pour résultat le retour de 0.

132
Martijn Pieters

Si B est un tableau booléen, écrivez

B=B*1

(Un peu de code golfy)

115
Chipotle

Si vous avez besoin d'une conversion à usage général à partir d'une chaîne qui n'est pas en soi un bool, mieux vaut écrire une routine similaire à celle décrite ci-dessous. Fidèle à l'esprit de la dactylographie, je n'ai pas passé l'erreur en silence, mais l'a convertie comme il convient pour le scénario actuel.

>>> def str2bool(st):
try:
    return ['false', 'true'].index(st.lower())
except (ValueError, AttributeError):
    raise ValueError('no Valid Conversion Possible')


>>> str2bool('garbaze')

Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    str2bool('garbaze')
  File "<pyshell#105>", line 5, in str2bool
    raise TypeError('no Valid COnversion Possible')
TypeError: no Valid Conversion Possible
>>> str2bool('false')
0
>>> str2bool('True')
1
7
Abhijit

Vous pouvez utiliser x.astype('uint8')x est votre tableau booléen.

6
shahar_m

Voici encore une autre solution à votre problème:

def to_bool(s):
    return 1 - sum(map(ord, s)) % 2
    # return 1 - sum(s.encode('ascii')) % 2  # alternative for python3

Cela fonctionne parce que la somme des codes ASCII de 'true' est 448, qui est paire, tandis que la somme des codes ASCII de 'false' est 523 ce qui est impair.


La chose amusante avec cette solution est que son résultat est assez aléatoire si l’entrée est pas l’un des 'true' ou 'false'. La moitié du temps, il retournera 0, et l'autre moitié 1. La variante utilisant encode lèvera une erreur de codage si l'entrée n'est pas ASCII (augmentant ainsi le caractère non défini du comportement).


Sérieusement, je pense que la solution la plus lisible et plus rapide consiste à utiliser un if:

def to_bool(s):
    return 1 if s == 'true' else 0

Voir quelques micro-repères:

In [14]: def most_readable(s):
    ...:     return 1 if s == 'true' else 0

In [15]: def int_cast(s):
    ...:     return int(s == 'true')

In [16]: def str2bool(s):
    ...:     try:
    ...:         return ['false', 'true'].index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [17]: def str2bool2(s):
    ...:     try:
    ...:         return ('false', 'true').index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [18]: def to_bool(s):
    ...:     return 1 - sum(s.encode('ascii')) % 2

In [19]: %timeit most_readable('true')
10000000 loops, best of 3: 112 ns per loop

In [20]: %timeit most_readable('false')
10000000 loops, best of 3: 109 ns per loop

In [21]: %timeit int_cast('true')
1000000 loops, best of 3: 259 ns per loop

In [22]: %timeit int_cast('false')
1000000 loops, best of 3: 262 ns per loop

In [23]: %timeit str2bool('true')
1000000 loops, best of 3: 343 ns per loop

In [24]: %timeit str2bool('false')
1000000 loops, best of 3: 325 ns per loop

In [25]: %timeit str2bool2('true')
1000000 loops, best of 3: 295 ns per loop

In [26]: %timeit str2bool2('false')
1000000 loops, best of 3: 277 ns per loop

In [27]: %timeit to_bool('true')
1000000 loops, best of 3: 607 ns per loop

In [28]: %timeit to_bool('false')
1000000 loops, best of 3: 612 ns per loop

Remarquez comment la solution if est au moins 2.5x fois plus rapidement que toutes les autres solutions. Cela n'a pas de sens de ne pas utiliser ifs sauf s'il s'agit d'une sorte de devoir (dans ce cas, vous ne devriez pas 'ai pas demandé cela en premier lieu).

6
Bakuriu