2012-05-03 11 views
26

Lo pregunto porque sé que el camino Pythonic para comprobar si una lista está vacía o no es lo siguiente:¿Por qué "[] == False" evalúa a False cuando "if not []" tiene éxito?

my_list = [] 
if not my_list: 
    print "computer says no" 
else: 
    # my_list isn't empty 
    print "computer says yes" 

imprimirá computer says no, etc. Así que esto me lleva a identificar [] con False verdad -valores; Sin embargo, si trato de comparar [] y False "directamente", me obtener lo siguiente:

>>> my_list == False 
False 
>>> my_list is False 
False 
>>> [] == False 
False 

etc ...

lo que está pasando aquí? Siento que me estoy perdiendo algo realmente obvio.

+4

Este es un gran diseño, ya que también permite que los programadores no usen la cláusula 'if variable == True:'. Debería ser 'si la variable es verdadera:' (Es exactamente cierto, no cualquier otra cosa - No es la mejor manera de hacer las cosas en la mayoría de los casos), o 'si variable' (es verdad-y). – Darthfett

Respuesta

49

La instrucción if evalúa todo en un contexto booleano, es como si hubiera una llamada implícita a la función incorporada bool().

Aquí es cómo usted realmente comprobar cómo las cosas van a ser evaluados por un if declaración:

>>> bool([]) 
False 
>>> bool([]) == False 
True 

Consulte la documentación sobre Truth Value Testing, listas vacías son considerados falsa, pero esto no significa que sean equivalente a False.

PEP 285 también tiene excelente información sobre por qué se llevó a cabo de esta manera, consulte la última bala en las Problemas resueltos sección para la parte que se ocupa de x == True y x == False específicamente.

El aspecto más convincente para mí es que == generalmente es transitivo, por lo a == b y b == c implica a == c. Por lo tanto, si fuera la forma esperada y [] == False eran verdaderos y '' == False eran verdaderos, se podría suponer que [] == '' debería ser verdadero (aunque obviamente no debería estar en un lenguaje sin conversión de tipo implícita).

+18

"Aunque obviamente no debería ser así," *** Javascript ***. –

13

Los contenedores vacíos son "falsy", es decir, evalúan a Falseen un contexto booleano. Eso no quiere decir que sean literalmente iguales a la constante False.

En otras palabras, la siguiente es True:

bool([]) == False 

el valor de verdad de un objeto está determinada por su __nonzero__() o su método __len__(). (En Python 3, __nonzero__() se ha cambiado el nombre a __bool__()). Los contenedores tienen un método __len__(), por lo que son ciertos cuando tienen algo en ellos y falsean cuando están vacíos.

Si los contenedores vacíos fueron literalmente iguales a False, por cierto, cualquier contenedor vacío sería igual a cualquier otro contenedor vacío: por ejemplo, {} == "" sería True. ¡Y eso simplemente no tendría ningún sentido!

Sin embargo, sólo para soplar su mente, lo siguiente es True:

False == 0 

Esto se debe a Booleanos son una subclase de los números enteros en Python, y False es básicamente sólo un cero que se imprime un poco diferente.

7

Los tipos incorporados en Python tienen un valor de verdad que les permite probar su veracidad. Ver Truth Value Testing.

Esto es diferente a decir object == False que está haciendo una prueba de valor real (prueba de igualdad). Está utilizando el método de los objetos __eq__() para determinar si sus valores son iguales.

+0

Encuentro esta la respuesta más útil, personalmente. La verdad es un concepto interesante y puede llevar a algunas consecuencias poco intuitivas. Tome JavaScript y sus valores inferiores como ejemplo. – dwerner

+1

@dwerner: Sí, estoy de acuerdo. Solo trato de pensarlo como "si este objeto tiene contenido" cuando digo 'if object:' – jdi

3

En su ejemplo, el operador no está causando que su lista se convierta a un booleano. Pruebe esto:

>>> not [] 
True 

>>> not [1] 
False 

"is" and "==" no hacen esa conversión.

+3

. Este es un buen punto que el operador 'not' está convirtiendo a booleano, pero lo tienes al revés. '(not []) == True' and' (not [1]) == False'. –

+0

Gracias. Lo arreglaré. –

Cuestiones relacionadas