¿False == 0 y True == 1 son un detalle de implementación o está garantizado por el lenguaje?

Resuelto Eric O. Lebigot asked hace 14 años • 4 respuestas

¿Está garantizado que False == 0and True == 1, en Python (suponiendo que el usuario no los reasigne)? Por ejemplo, ¿se garantiza de alguna manera que el siguiente código siempre producirá los mismos resultados, cualquiera que sea la versión de Python (tanto la existente como, probablemente, la futura)?

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

¡Cualquier referencia a la documentación oficial sería muy apreciada!

Como se señaló en muchas respuestas, boolhereda de int. Por lo tanto, la pregunta puede reformularse como: "¿Dice oficialmente la documentación que los programadores pueden confiar en valores booleanos heredados de números enteros, con los valores 0y1 ?". ¡Esta pregunta es relevante para escribir código sólido que no fallará debido a los detalles de implementación!

Eric O. Lebigot avatar May 04 '10 16:05 Eric O. Lebigot
Aceptado

En Python 2.x esto no está garantizado ya que es posible Truereasignarlo False. Sin embargo, incluso si esto sucede, los valores booleanos True y boolean False se devuelven correctamente para realizar comparaciones.

En Python 3.x Truey Falseson palabras clave y siempre serán iguales a 1y 0.

En circunstancias normales en Python 2 y siempre en Python 3:

FalseEl objeto es de tipo boolque es una subclase de int:

    object
       |
     int
       |
     bool

Es la única razón por la que en su ejemplo ['zero', 'one'][False]funciona. No funcionaría con un objeto que no sea una subclase de un número entero, porque la indexación de listas solo funciona con números enteros u objetos que definen un __index__método (gracias mark-dickinson ).

Editar:

Es cierto para la versión actual de Python y para la de Python 3. Los documentos para Python 2 y los documentos para Python 3 dicen:

Hay dos tipos de números enteros: [...] Enteros (int) [...] Booleanos (bool)

y en la subsección booleana:

Booleanos: Representan los valores de verdad Falso y Verdadero [...] Los valores booleanos se comportan como los valores 0 y 1, respectivamente, en casi todos los contextos, con la excepción de que cuando se convierten en una cadena, las cadenas "Falso" o "Verdadero " se devuelven, respectivamente.

También existe, para Python 2 :

En contextos numéricos (por ejemplo, cuando se usan como argumento de un operador aritmético), [Falso y Verdadero] se comportan como los números enteros 0 y 1, respectivamente.

Por lo tanto, los valores booleanos se consideran explícitamente números enteros en Python 2 y 3.

Así que estarás a salvo hasta que llegue Python 4. ;-)

Olivier Verdier avatar May 04 '2010 09:05 Olivier Verdier

Aquí está el PEP que analiza el nuevo tipo bool en Python 2.3: http://www.python.org/dev/peps/pep-0285/ .

Al convertir un bool en un int, el valor entero es siempre 0 o 1, pero al convertir un int en un bool, el valor booleano es Verdadero para todos los números enteros excepto 0.

>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False
Erik Cederstrand avatar May 04 '2010 09:05 Erik Cederstrand

En Python 2.x, no está garantizado en absoluto:

>>> False = 5
>>> 0 == False
False

Entonces podría cambiar. En Python 3.x, Verdadero, Falso y Ninguno son palabras reservadas , por lo que el código anterior no funcionaría.

En general, con los valores booleanos debes asumir que, si bien False siempre tendrá un valor entero de 0 (siempre que no lo cambies, como se indicó anteriormente), True podría tener cualquier otro valor. No confiaría necesariamente en ninguna garantía True==1, pero en Python 3.x, este siempre será el caso, pase lo que pase.

Daniel G avatar May 04 '2010 09:05 Daniel G

Dividamos esta pregunta en dos partes.

Pitón:

print(45 == "45")  # Output - False

JavaScript:

console.log(45 == "45")  # Output - true

Aquí, la mayoría de la gente piensa que Javascript solo verifica el valor de ambos objetos laterales, pero eso no es cierto. La escritura console.log(45 == "45")es similar a print(45 == "45").
Pero ahora tienes una pregunta, si ambas sintaxis son similares, ¿por qué obtengo resultados diferentes?

En Javascript:

  • El ==operador realiza coerción de tipo antes de comparar los valores. Esto significa que JavaScript intentará convertir los operandos a un tipo común antes de evaluar la igualdad.
  • En el caso de 45 == "45"JavaScript, la cadena "45"se convierte automáticamente en un número porque el otro operando es un número. JavaScript intenta realizar una conversión de tipos implícita para realizar la comparación. La cadena "45"se puede convertir al número 45y, por tanto, la comparación 45 == "45"se evalúa como true.
  • Similar a la palabra clave de Python is, Javascript tiene un ===operador de comparación. Lo que verifica que ambos objetos laterales estén ubicados en la misma ubicación de memoria RAM de la computadora o no.

En Python:

  • En Python, 45ya "45"tenemos diferentes tipos. 45es una instancia de class <integer>y "45"es una instancia de class <string>. No son instancias de la misma clase.
  • A diferencia de Javascript, Python no realiza conversión de tipos interna, por lo que print(45 == "45")la evalúa False.
  • Python usó conversión de tipo interna. Sí, escuchaste bien, pero aquí hay una condición. Python utilizará la conversión de tipos interna solo con booleanobjetos de tipo.
  • Entonces, en la expresión print(True == 1), el valor booleano True se convierte implícitamente en un número entero 1antes de realizar la comparación. Como resultado, print(1 == 1)se evalúa la comparación, que es True.
  • Cuando se escribe print(True == 1)equivale a print(1 == 1). Cuando el intérprete de Python llega a este código de línea antes de ejecutar este código, se convierte print(True == 1)a print(int(True) == 1), por lo que finalmente se convierte print(1 == 1)y ahora, de acuerdo con ==la regla, ambos objetos laterales valueson type <class int>iguales, por lo que se ve Trueel resultado en la terminal.
  • De manera similar, print(False == 0)es equivalente a print(int(False) == 0)y finalmente print(0 == 0)evalúa a True.

Chequea aquí.

# Normal behavior
sample_1 = True
print(sample_1) # Output - True
print(int(sample_1)) # Output - 1

sample_2 = False
print(sample_2) # Output - False
print(int(sample_2)) # Output - 0


# Try with True - boolean
A = True + 5  # equivalent to `A = int(True) + 5`
print(A) # Output - 6 (True ---> 1)


# Try with False - boolean
B = False + 5 # equivalent to `A = int(False) + 5`
print(B) # Output - 5 (False ---> 0)


# Try both boolean together
final = False + True # equivalent to `final = int(False) + int(True)`
print(final) # Output - 1  (False ---> 0 & True ---> 1)

¡Espero que ayude a todos!

Dhaval Gojiya avatar Jun 29 '2023 14:06 Dhaval Gojiya