Compare si dos variables hacen referencia al mismo objeto en Python

Respuestas:

133

Para eso ises: x is ydevuelve Truesi xy yson el mismo objeto.

Jochen Ritzel
fuente
6
En el ejemplo, x is zdevuelve False. Pero si a xyz se les asignan los mismos valores en lugar de listas (por ejemplo x, z = 13, 13), entonces x is zretorna True. ¿Porqué es eso?
Proyecto de ley
12
@Bill: Ese es un artefacto de cómo Python maneja los ints. Python asigna objetos enteros a los que xy zapuntan. Dado que los números enteros pequeños son un error común (-1 como valor de error, 0 cada vez que indexa algo, los números pequeños suelen ser valores predeterminados razonables) Python optimiza preasignando números pequeños (-5 a 256) y reutiliza el mismo objeto entero. Por lo tanto, su ejemplo solo funciona para números en este rango. Intente asignar algo más grande, es decir 270. Para obtener más información, consulte aquí
ted
1
@AndresR No, eso está mal. iscomprueba si dos nombres hacen referencia a la misma ubicación de memoria. No tiene nada que ver con el objeto en sí. Es fácil tener objetos inmutables como cadenas que son iguales pero que no se almacenan en la misma ubicación, por ejemplo, ''a'*10000 is 'a' * 10000es Falso.
Jochen Ritzel
1
@JochenRitzel Tienes toda la razón, ¡gracias por este comentario! Entonces, no entiendo qué está pasando con "af" is "af"o () is ()... ¿por qué comparten la misma ubicación de memoria?
AndresR
2
@AndreasR Para cadenas / números literales en el código, el compilador verifica que existan solo una vez y los reutiliza. Los valores especiales como (), Ninguno, Verdadero, Falso, etc. también se definen como singletons. Durante la ejecución, el tiempo de ejecución también intenta reutilizar pequeños números y cadenas, pero al final es una compensación entre la velocidad y la memoria y lo que sucede depende de cómo se implementó el tiempo de ejecución de Python.
Jochen Ritzel
12

y is xserá True, y is zserá False.

Mark Rushakoff
fuente
11

Si bien las dos soluciones correctas x is zy id(x) == id(z)ya se han publicado, quiero señalar un detalle de implementación del pitón. Python almacena enteros como objetos, como optimización genera un montón de pequeños enteros al principio (-5 a 256) y apunta CADA variable que contiene un entero con un valor pequeño a estos objetos preinicializados.Más información

Esto significa que para los objetos enteros inicializados con los mismos números pequeños (-5 a 256), la verificación de si dos objetos son iguales devolverá verdadero ( ON C-Pyhon , hasta donde yo sé, esto es un detalle de implementación ), mientras que para los más grandes números, esto solo devuelve verdadero si un objeto se inicializa del otro.

> i = 13
> j = 13
> i is j
True

> a = 280
> b = 280
> a is b
False

> a = b
> a
280
> a is b
True
ted
fuente
python3.6: a = 98765; b = 98765; a es b => Verdadero. Algo ha cambiado aparentemente.
Mikhail Kalashnikov
@MikhailKalashnikov Nope. Probé en Python 3.6.2, esto todavía existe.
nix
todavía existe en Python 3.7.7
Bill Huang
9

También puede usar id () para verificar a qué objeto único se refiere cada nombre de variable.

In [1]: x1, x2 = 'foo', 'foo'

In [2]: x1 == x2
Out[2]: True

In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)

In [4]: x2 = 'foobar'[0:3]

In [5]: x2
Out[5]: 'foo'

In [6]: x1 == x2
Out[6]: True

In [7]: x1 is x2
Out[7]: False

In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)
Cuenta
fuente
La nota de @ ted sobre el uso de id es bastante relevante aquí.
Leo Ufimtsev
2

Realmente me gusta tener una retroalimentación visual, por eso a veces abro http://www.pythontutor.com/visualize.html#mode=edit para ver cómo se asigna la memoria y qué hace referencia a qué.

ingrese la descripción de la imagen aquí

Se agregó este increíble gif ya que esta respuesta trata sobre visualizar ...

usuario1767754
fuente
2

Esto es de docs.python.org: "Cada objeto tiene una identidad, un tipo y un valor. La identidad de un objeto nunca cambia una vez que ha sido creado; puede pensar en él como la dirección del objeto en la memoria. El operador 'es' compara la identidad de dos objetos; la función id () devuelve un número entero que representa su identidad ".

Aparentemente, cada vez que cambia el valor, el objeto se recrea como lo indica el cambio de identidad. La línea x = 3 seguida de la línea x = 3,14 no da error y da diferentes identidades, tipos y valores para x.

Scott Woods
fuente
1
Excelente captura de doc.
prosti