¿Es Pythonic usar bools como ints?

False es equivalente a 0 y True es equivalente a 1 por lo que es posible hacer algo como esto:

 def bool_to_str(value): """value should be a bool""" return ['No', 'Yes'][value] bool_to_str(True) 

Observe cómo el valor es bool pero se usa como un int .

¿Es este el tipo de uso Pythonic o debería ser evitado?

Seré la voz extraña (ya que todas las respuestas están denunciando el uso del hecho de que False == 0 y True == 1 , según lo garantiza el lenguaje) ya que afirmo que el uso de este hecho para simplificar su código es perfectamente multa.

Históricamente, las operaciones lógicas de verdadero / falso tendían a usar simplemente 0 para falso y 1 para verdadero; En el transcurso del ciclo de vida de Python 2.2, Guido notó que demasiados módulos comenzaron con asignaciones como false = 0; true = 1 false = 0; true = 1 y esto produjo una variante y una variación inútil (esto último porque el uso de mayúsculas de true y false estaba por todas partes; algunos usaban mayúsculas, otras en minúsculas, algunas iniciales) y así introdujeron la subclase bool de int y sus constantes True y False .

Hubo bastante rechazo en ese momento, ya que muchos de nosotros temíamos que los novatos de Python utilizarían el tipo y las constantes para restringir las habilidades del idioma, pero Guido estaba convencido de que solo éramos pesimistas: nadie entendería tan mal a Python. por ejemplo, para evitar el uso perfectamente natural de False y True como índices de lista, o en un resumen, u otros modismos perfectamente claros y útiles.

Las respuestas a este hilo demuestran que teníamos razón: como temíamos, surgió un malentendido total de los roles de este tipo y las constantes, y la gente está evitando y, lo que es peor, instando a otros a evitar, construcciones de Python perfectamente naturales a favor de giros inútiles.

Luchando contra la marea de semejante malentendido, insto a todos a usar Python como Python , no tratar de forzarlo en el molde de otros idiomas cuya funcionalidad y estilo preferido son muy diferentes. En Python , Verdadero y Falso son 99.9% como 1 y 0, diferenciándose exclusivamente en su forma str(...) (y, por lo tanto, repr(...) ) – para cualquier otra operación, excepto la estratificación, siéntase libre de usarlos sin contorsiones. Eso se aplica a la indexación, la aritmética, las operaciones de bits, etc., etc., etc.

Estoy con Alex. False==0 y True==1 , y no hay nada de malo en eso.

Aún así, en Python 2.5 y más adelante escribiría la respuesta a esta pregunta en particular usando la expresión condicional de Python:

 def bool_to_str(value): return 'Yes' if value else 'No' 

De esa manera, no hay ningún requisito de que el argumento sea realmente un bool, como if x: ... acepta cualquier tipo para x , la función bool_to_str() debería hacer lo correcto cuando se pasa Ninguno, una cadena, una lista, o 3.14.

seguramente:

 def bool_to_str(value): "value should be a bool" return 'Yes' if value else 'No' 

es más legible.

Su código parece inexacto en algunos casos:

 >>> def bool_to_str(value): ... """value should be a bool""" ... return ['No', 'Yes'][value] ... >>> bool_to_str(-2) 'No' 

Y te recomiendo que uses solo el operador condicional para facilitar la lectura:

 def bool_to_str(value): """value should be a bool""" return "Yes" if value else "No" 

En realidad, es una característica del lenguaje que False == 0 y True == 1 (no depende de la implementación): es False == 0 y True == 1 en Python es un detalle de implementación o está garantizado por el lenguaje ?

Sin embargo, estoy de acuerdo con la mayoría de las otras respuestas: hay formas más legibles de obtener el mismo resultado que ['No', 'Yes'][value] , mediante el uso de … if value else … o de un diccionario , que tienen las ventajas respectivas de sugerir y afirmar que el value es un booleano.

Además, el … if value else … sigue la convención habitual de que no-0 es Verdadero: también funciona incluso cuando el value == -2 (el valor es Verdadero), como lo indica la dalia. Los enfoques de lista y dictado no son tan robustos, en este caso, por lo que no los recomendaría.

Usar un bool como int es bastante correcto porque bool es la subclase s de int.

 >>> isinstance(True, int) True >>> isinstance(False, int) True 

Acerca de su código: ponerlo en una función de una línea como la que se encuentra en la parte superior. Los lectores deben encontrar la fuente de su función o los documentos y leerlos (el nombre de la función no le dice mucho). Esto interrumpe el flujo. Simplemente colóquelo en línea y no use una lista (creada en tiempo de ejecución), use una tupla (creada en tiempo de comstackción si los valores son constantes). Ejemplo:

 print foo, bar, num_things, ("OK", "Too many!)[num_things > max_things] 

Personalmente, creo que depende de cómo desea utilizar este hecho, aquí hay dos ejemplos.

  1. Simplemente use boolean como una statement condicional está bien. La gente hace esto todo el tiempo.

     a = 0 if a: do something 
  2. Sin embargo, diga que desea contar cuántos elementos ha tenido éxito, el código tal vez no sea muy fácil de leer para otras personas.

     def succeed(val): if do_something(val): return True else: return False count = 0 values = [some values to process] for val in values: count += succeed(val) 

Pero veo el código de producción como este.

 all_successful = all([succeed(val) for val in values]) at_least_one_successful = any([succeed(val) for val in values]) total_number_of_successful = sum([succeed(val) for val in values])