Come verificare se due variabili fanno riferimento allo stesso oggetto?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Come verificare se due variabili fanno riferimento allo stesso oggetto?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Risposte:
Ecco a cosa isserve: x is yrestituisce Truese xe ysono lo stesso oggetto.
x is zritorna False. Ma se a xez vengono assegnati gli stessi valori invece di elenchi (ad esempio x, z = 13, 13), x is zrestituisce True. Perché?
xe z. Poiché i piccoli numeri interi sono comuni (-1 come valore di errore, 0 ogni volta che si indicizza effettivamente qualcosa, i piccoli numeri sono di solito valori predefiniti ragionevoli) Python ottimizza preallocando piccoli numeri (da -5 a 256) e riutilizza lo stesso oggetto intero. Quindi il tuo esempio funziona solo per i numeri in questo intervallo. Prova ad assegnare qualcosa di più grande, ad es 270. Per maggiori informazioni guarda qui
iscontrolla se due nomi fanno riferimento alla stessa posizione di memoria. Non ha nulla a che fare con l'oggetto stesso. È facile avere oggetti immutabili come stringhe uguali ma non archiviate nella stessa posizione, ad esempio ''a'*10000 is 'a' * 10000False.
"af" is "af"o () is ()... perché condividono la stessa posizione di memoria?
y is xsarà True, y is zsarà False.
Mentre le due soluzioni corrette x is ze id(x) == id(z)sono già state pubblicate, voglio sottolineare un dettaglio di implementazione di python. Python memorizza gli interi come oggetti, come ottimizzazione genera un gruppo di piccoli interi all'inizio (da -5 a 256) e punta OGNI variabile che contiene un numero intero con un piccolo valore a questi oggetti preinizializzati. Ulteriori informazioni
Ciò significa che per oggetti interi inizializzati con gli stessi piccoli numeri (da -5 a 256) il controllo se due oggetti sono uguali restituirà true ( ON C-Pyhon , per quanto ne so questo è un dettaglio di implementazione ), mentre per più grandi numeri questo restituisce vero solo se un oggetto viene inizializzato dall'altro.
> i = 13
> j = 13
> i is j
True
> a = 280
> b = 280
> a is b
False
> a = b
> a
280
> a is b
True
Puoi anche usare id () per controllare a quale oggetto univoco si riferisce ogni nome di variabile.
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)
Mi piace molto avere un feedback visivo, ecco perché a volte apro semplicemente http://www.pythontutor.com/visualize.html#mode=edit per vedere come viene allocata la memoria e cosa fa riferimento a cosa.
Aggiunta questa fantastica gif poiché questa risposta riguarda la visualizzazione ..
Questo è da docs.python.org: "Ogni oggetto ha un'identità, un tipo e un valore. L'identità di un oggetto non cambia mai una volta che è stato creato; potresti pensarlo come l'indirizzo dell'oggetto in memoria. L'operatore 'is' confronta l'identità di due oggetti; la funzione id () restituisce un numero intero che ne rappresenta l'identità. "
Apparentemente ogni volta che cambi il valore l'oggetto viene ricreato come indicato dal cambio di identità. La riga x = 3 seguita dalla riga x = 3.14 non dà errori e fornisce identità, tipi e valori diversi per x.