2016-07-04 20 views
35

due variabili in Python hanno la stessa id:Due variabili in Python hanno lo stesso ID, ma non elenchi o tuple

a = 10 
b = 10 
a is b 
>>> True 

Se prendo due list s:

a = [1, 2, 3] 
b = [1, 2, 3] 
a is b 
>>> False 

in base alle this link Senderle ha risposto che i riferimenti a oggetti immutabili hanno lo stesso id e gli oggetti mutabili come le liste hanno id differenti.

Così ora secondo la sua risposta, tuple dovrebbe avere lo stesso ID - che significa:

a = (1, 2, 3) 
b = (1, 2, 3) 
a is b 
>>> False 

Idealmente, come tuple non sono mutabili, dovrebbe restituire True, ma sta tornando False!

Qual è la spiegazione?

+0

si deve distinguere tra le variabili e gli oggetti (liste e tuple) - quando si confrontano due oggetti come questo si confrontare i loro indirizzi di memoria che si differenziano, pur avendo stessa lista e tuple elementi. – dmitryro

+13

Penso che tu abbia frainteso la risposta a cui ti colleghi. Oggetti distinti e immutabili hanno differenti identificazioni. Ma per interi <256 (sulla maggior parte degli interpreti) il valore è precaricato in memoria e quindi nel tuo primo esempio a è b –

+0

Grazie @JacquesGaudin! Mi fa capire per ora. –

risposta

44

Gli oggetti non modificabili non hanno lo stesso id e, di fatto, questo non è vero per qualsiasi tipo di oggetto definito separatamente. Ogni volta che definisci un oggetto in Python, creerai un nuovo oggetto con una nuova identità.

Ma ci sono alcune eccezioni per numeri interi piccoli (tra -5 e 256) e stringhe piccole (stringhe internamente, con una lunghezza speciale (di solito inferiore a 20 caratteri)) che sono singleton e hanno lo stesso id (in realtà un oggetto con puntatore multiplo). È possibile controllare questo fatto come segue:

>>> 30 is 20 + 10 
True 
>>> 
>>> 300 is 200 + 100 
False 
>>> 'aa' * 2 is 'a' * 4 
True 
>>> 'aa' * 20 is 'a' * 40 
False 

E per un oggetto personalizzato:

>>> class A: 
... pass 
... 
>>> A() is A() # Every time you create an instance you'll have a new instance with new identity 
False 

Si noti inoltre che l'operatore is controllerà l'identità dell'oggetto, non il valore. Se si desidera controllare il valore che si dovrebbe usare ==:

>>> 300 == 3*100 
True 

E dal momento che non esiste una regola per le tuple (altri tipi) Se si definiscono le due stesse tuple in qualsiasi formato che otterranno i propri ID:

>>> a = (1,) 
>>> b = (1,) 
>>> 
>>> a is b 
False 

e si noti che il fatto di numeri interi Singleton e internati stringhe è vero anche quando li si definisce all'interno di oggetti mutabili e immutabili:

>>> a = (100, 700, 400) 
>>> 
>>> b = (100, 700, 400) 
>>> 
>>> a[0] is b[0] 
True 
>>> a[1] is b[1] 
False 
+0

nell'ultimo esempio menzionato (di tuple): a [1] è b [1] dovrebbe essere True, perché restituito False? –

+4

@Ram Perché pensi che dovrebbe restituire True, sono 2 oggetti separati (interi) ma con lo stesso valore (non id). E nota che non sono inferiori a 256. – Kasramvd

+1

sì, d'accordo. Penso che solo gli interi <256 restituiranno ids() vero. qualsiasi numero intero maggiore di 256 nell'interprete python avrà il proprio spazio id, i valori saranno gli stessi. –

19

Immutabile != stesso oggetto.*

An immutable object is simply an object whose state cannot be altered; e questo è tutto. Quando viene creato un nuovo oggetto, viene assegnato un nuovo indirizzo allo. Come tale, controllando se gli indirizzi sono uguali a is restituirà False.

Il fatto che 1 is 1 o "a" is "a" rendimenti True è dovuto a integer caching e la stringa interning eseguito da Python in modo da non lasciare che ti confondere; non è correlato con gli oggetti in questione essendo mutevoli/immutabili.


* oggetti immutabili vuoti do refer to the same object e la loro is ness fa ritorno vero, questo è un caso particolare specifica implementazione, però.

15

Date un'occhiata a questo codice:

>>> a = (1, 2, 3) 
>>> b = (1, 2, 3) 
>>> c = a 
>>> id(a) 
178153080L 
>>> id(b) 
178098040L 
>>> id(c) 
178153080L 

Al fine di capire perché a is c viene valutata come True mentre a is b rendimenti False vi raccomando vivamente di eseguire passo-passo frammento di sopra del Online Python Tutor. La rappresentazione grafica degli oggetti in memoria ti fornirà una visione più approfondita di questo problema (sto allegando uno screenshot).

enter image description here

Problemi correlati