Cómo convertir 'falso' a 0 y 'verdadero' a 1 en Python


119

¿Hay alguna forma de convertir el truetipo unicodea 1 y el falsetipo unicodea 0 (en Python)?

Por ejemplo: x == 'true' and type(x) == unicode

quiero x = 1

PD: no quiero usar if- else.

Respuestas:


165

Usar int()en una prueba booleana:

x = int(x == 'true')

int()convierte el booleano en 1o 0. Tenga en cuenta que cualquier valor que no sea igual a 'true'resultará en 0ser devuelto.


Esta es una respuesta maravillosa, excepto que todo lo que no sea "verdadero" se interpretaría como "0". No estoy seguro de si eso se adaptaría a los requisitos de los OP.
Abhijit

Aunque probablemente sea lo que quería el OP, no coincide exactamente con la pregunta que se hizo para python 2.7. Pidieron explícitamente que funcionara en tipo Unicode y no especificaron el comportamiento del tipo str.
wim

1
@wim En realidad, la pregunta nunca menciona una versión de Python, y mucho menos el hecho de que debería ser Python2. 7 . También tenga en cuenta que en python2 u'true' == 'true'la función se comporta correctamente independientemente del tipo de entrada [entre stry unicode].
Bakuriu

Pero Bakuriu, ese es exactamente mi punto, el "problema" es ese u'true' == 'true'y que no sabemos cuál es el caso de uso. Quizás quieran un comportamiento diferente para la situación en la que type(x) != unicode.
wim

1
@AlbertChen: no, porque las matrices numpy transmiten comparaciones y no producen un valor booleano. En cambio, las comparaciones producen una matriz de valores booleanos. No estoy seguro de lo que espera de una arrayvalue == 'true'comparación, la pregunta que respondí aquí es específica de un valor de cadena (Unicode).
Martijn Pieters

136

Si Bes una matriz booleana, escriba

B = B*1

(Un código de bits golfy).


1
Exactamente lo mismo también funciona para valores individuales. ¡Esto es genial!
user31415

2
No funciona para mí en Python 3 (la matriz permanece booleana). Pero el uso numpy.multiply(B,1)funciona.
Alaa M.

¡esto funciona para mí en Python 3! y una solución tan brillante. oh mi
haciendo preguntas

@Ourobours: Tratar de seguir tu sugerencia no funcionó para mí. Si bien el sulotion original dio un resultado agradable y viable, me B=map(int,B)devolvió un objeto de mapa en Python 3.
Eulenfuchswiesel

1
@Eulenfuchswiesel Esto se debe a que map devuelve un iterador en Python3. Para usarlo como una lista, conviértalo como una lista así: B = list (map (int, B))
Gigi Bayte 2

11

Puede usar x.astype('uint8')dónde xestá su matriz booleana.


9

Aquí hay otra solución más a su problema:

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

Funciona porque la suma de los códigos ASCII de 'true'es 448, que es par, mientras que la suma de los códigos ASCII de 'false'es 523que es impar.


Lo curioso de esta solución es que su resultado es bastante aleatorio si la entrada no es una de 'true'o 'false'. La mitad de las veces volverá 0y la otra mitad 1. La variante que usa encodegenerará un error de codificación si la entrada no es ASCII (aumentando así la indefinición del comportamiento).


En serio, creo que la solución más fácil de leer y más rápida es usar un if:

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

Vea algunos microbenchmarks:

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

Observe cómo la ifsolución es al menos 2,5 veces más rápida que todas las demás soluciones. No , no tiene sentido poner como requisito para evitar el uso de ifs, excepto si se trata de algún tipo de tarea (en cuyo caso no debería haber hecho esta en el primer lugar).


7

Si necesita una conversión de propósito general de una cadena que per se no es un bool, es mejor que escriba una rutina similar a la que se muestra a continuación. De acuerdo con el espíritu de la escritura pato, no pasé el error silenciosamente, sino que lo convertí según corresponda para el escenario actual.

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

2
¿Por qué un TypeError? Si la cadena no contiene 'true'o 'false'es un error de valor . Si la entrada no es una cadena, obtendrá (99,99% de las veces) un AttributeErroren su lugar, por lo que es inútil buscarlo ValueErrory volver a subirlo como TypeError.
Bakuriu

@Bakuriu: Estoy de acuerdo. TypeError de hecho no era aplicable aquí.
Abhijit

@Bakuriu: solo por curiosidad, ¿podrías dar un ejemplo de cómo indexgenerar un AttributeError?
georg

@Bakuriu: Creo que me refiero más bien a su puesto a continuación: return ['false', 'true'].index(s) except (ValueError, AttributeError).
georg

@ thg435 En esa publicación, simplemente copié y pegué y decidí eliminar la lower()llamada, ya que esta era la única solución que hacía este cálculo adicional y no habría sido correcto incluirla en el micro-benchmark. Claro que incluso try...excepttomará un poco de tiempo, pero la diferencia es pequeña si no se plantea ninguna excepción (como 20nsmenos o así).
Bakuriu

0

bool a int: x = (x == 'true') + 0

Ahora la x contiene 1 si x == 'true'más 0.

Nota: x == 'true'devolverá bool, que luego se convertirá en int que tiene valor (1 si el valor bool es True en caso contrario 0) cuando se agregue con 0.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.