Comprender el operador "es" [duplicado]

Resuelto aniskhan001 asked hace 11 años • 11 respuestas

El isoperador no hace coincidir los valores de las variables, sino las instancias mismas.

que significa realmente?

Declaré dos variables nombradas xy yasignando los mismos valores en ambas variables, pero devuelve falso cuando uso el isoperador.

Necesito una aclaración. Aquí está mi código:

x = [1, 2, 3]
y = [1, 2, 3]

print(x is y)  # False
aniskhan001 avatar Dec 01 '12 00:12 aniskhan001
Aceptado

No entendiste lo que isprueba el operador. Prueba si dos variables apuntan al mismo objeto , no si dos variables tienen el mismo valor.

De la documentación para el isoperador :

Los operadores isand is notprueban la identidad del objeto: x is yes verdadero si y solo si xy yson el mismo objeto.

Utilice el ==operador en su lugar:

print(x == y)

Esto imprime True. xy yson dos listas separadas :

x[0] = 4
print(y)  # prints [1, 2, 3]
print(x == y)   # prints False

Si usa la id()función, verá eso xy ytendrá diferentes identificadores:

>>> id(x)
4401064560
>>> id(y)
4401098192

pero si tuvieras que asignarlo, yambos xapuntan al mismo objeto:

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

y ismuestra que ambos son el mismo objeto, devuelve True.

Recuerde que en Python, los nombres son solo etiquetas que hacen referencia a valores ; puede tener varios nombres que apunten al mismo objeto. isLe indica si dos nombres apuntan a un mismo objeto. ==te dice si dos nombres se refieren a objetos que tienen el mismo valor.

Martijn Pieters avatar Nov 30 '2012 17:11 Martijn Pieters

Otro duplicado preguntaba por qué dos cadenas iguales generalmente no son idénticas, lo que en realidad no se responde aquí:

>>> x = 'a' 
>>> x += 'bc'
>>> y = 'abc'
>>> x == y
True
>>> x is y
False

Entonces, ¿por qué no son la misma cadena? Especialmente teniendo en cuenta esto:

>>> z = 'abc'
>>> w = 'abc'
>>> z is w
True

Dejemos un poco de lado la segunda parte. ¿Cómo podría ser cierto lo primero?

El intérprete tendría que tener una "tabla interna", una tabla que asigna valores de cadena a objetos de cadena, de modo que cada vez que intente crear una nueva cadena con el contenido 'abc', obtendrá el mismo objeto. Wikipedia tiene una discusión más detallada sobre cómo funcionan las prácticas.

Y Python tiene una tabla de internación de cadenas; puedes internar cadenas manualmente con el sys.internmétodo.

De hecho, Python puede internar automáticamente cualquier tipo inmutable, pero no es obligatorio hacerlo. Diferentes implementaciones internarán diferentes valores.

CPython (la implementación que estás usando si no sabes qué implementación estás usando) interna automáticamente enteros pequeños y algunos singletons especiales como False, pero no cadenas (ni enteros grandes, ni tuplas pequeñas, ni cualquier otra cosa). Puedes ver esto con bastante facilidad:

>>> a = 0
>>> a += 1
>>> b = 1
>>> a is b
True
>>> a = False
>>> a = not a
>>> b = True
a is b
True
>>> a = 1000
>>> a += 1
>>> b = 1001
>>> a is b
False

Vale, pero ¿por qué eran zidénticos w?

Ese no es el intérprete que realiza automáticamente la pasantía, sino los valores plegables del compilador.

Si la misma cadena en tiempo de compilación aparece dos veces en el mismo módulo (es difícil definir qué significa exactamente esto; no es lo mismo que una cadena literal, porque r'abc', 'abc'y 'a' 'b' 'c'son literales diferentes pero la misma cadena), pero es fácil de entender intuitivamente), el compilador solo creará una instancia de la cadena, con dos referencias.

De hecho, el compilador puede ir aún más lejos: el optimizador 'ab' + 'c'puede convertirlo 'abc', en cuyo caso se puede plegar junto con una 'abc'constante en el mismo módulo.

Nuevamente, esto es algo que Python está permitido pero no es obligatorio. Pero en este caso, CPython siempre pliega cadenas pequeñas (y también, por ejemplo, pequeñas tuplas). (Aunque el compilador declaración por declaración del intérprete interactivo no ejecuta la misma optimización que el compilador módulo a la vez, no verá exactamente los mismos resultados de forma interactiva).


Entonces, ¿qué deberías hacer al respecto como programador?

Pues nada. Casi nunca tienes motivos para preocuparte si dos valores inmutables son idénticos. Si quieres saber cuándo puedes usar a is ben lugar de a == b, estás haciendo la pregunta equivocada. Úselo siempre a == bexcepto en dos casos:

  • Para comparaciones más legibles con los valores singleton como x is None.
  • Para valores mutables, cuando necesite saber si la mutación xafectará el archivo y.
abarnert avatar Sep 10 '2014 05:09 abarnert

issólo devuelve verdadero si en realidad son el mismo objeto. Si fueran iguales, un cambio en uno también se mostraría en el otro. He aquí un ejemplo de la diferencia.

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]
Mark Ransom avatar Nov 30 '2012 17:11 Mark Ransom

Debido a una pregunta duplicada , esta analogía podría funcionar:

# - Darling, I want some pudding!
# - There is some in the fridge.

pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True

# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.

pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False
Amadan avatar Sep 10 '2014 04:09 Amadan