Python'da iki değişken aynı nesneye başvuruyorsa karşılaştırın


Yanıtlar:


135

Yani neyi en isiçindir: x is ydöner Trueeğer xve yaynı nesne bulunmaktadır.


6
Örnekte, x is zdöner False. Ancak, x ve z'ye listeler yerine (örneğin x, z = 13, 13) aynı değerler atanırsa x is zgeri döner True. Neden?
Bill

12
@Bill: Bu, python'un int'leri nasıl işlediğinin bir eseri. Python, tam sayı nesnelerini nereye xve znoktaya ayırır. Küçük tamsayılar sık ​​sık başarısız olduğu için (hata değeri olarak -1, bir şeyi gerçekten indekslediğinizde 0, küçük sayılar genellikle makul varsayılan değerlerdir) Python, küçük sayıları (-5 ila 256) önceden tahsis ederek optimize eder ve aynı tamsayı nesnesini yeniden kullanır. Dolayısıyla, örneğiniz yalnızca bu aralıktaki sayılar için işe yarar. Daha büyük bir şey atamayı deneyin, yani 270. Daha fazla bilgi için buraya bakın
ted

1
@AndresR Hayır, bu yanlış. isiki adın aynı bellek konumuna başvurup başvurmadığını kontrol eder. Nesnenin kendisiyle hiçbir ilgisi yoktur. Eşit olan ancak aynı konumda depolanmayan dizeler gibi değişmez nesnelere sahip olmak kolaydır, örneğin ''a'*10000 is 'a' * 10000False.
Jochen Ritzel

1
@JochenRitzel Tamamen haklısınız, bu yorum için teşekkür ederim! Öyleyse, ne olduğunu anlamıyorum "af" is "af"ya da () is ()... neden aynı hafıza konumunu paylaşıyorlar?
AndresR

2
@AndreasR Koddaki değişmez dizeler / sayılar için derleyici bunların yalnızca bir kez var olup olmadığını kontrol eder ve bunları yeniden kullanır. (), Yok, Doğru, Yanlış vb. Gibi özel değerler de tek ton olarak tanımlanmıştır. Yürütme sırasında çalışma zamanı da küçük sayıları ve dizeleri yeniden kullanmaya çalışır, ancak sonunda bu hız ve bellek arasında bir değiş tokuş olur ve ne olacağı Python çalışma zamanının nasıl uygulandığına bağlıdır.
Jochen Ritzel


11

Her bir değişken adının hangi benzersiz nesneyi ifade ettiğini kontrol etmek için id () öğesini de kullanabilirsiniz .

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)

@ ted'in kimlik kullanımına ilişkin notu burada oldukça önemlidir.
Leo Ufimtsev

11

İki doğru çözümler iken x is zve id(x) == id(z)önceden gönderilmiş, Python bir uygulama detay işaret etmek istiyorum. Python tam sayıları nesneler olarak depolar, bir optimizasyon olarak başlangıcında (-5 ila 256) bir grup küçük tam sayı üretir ve bu önceden başlatılmış nesnelere küçük bir değere sahip bir tam sayı tutan HER değişkene işaret eder. Daha fazla bilgi

Bu, aynı küçük sayılarla (-5 ila 256) başlatılan tamsayı nesneler için, iki nesnenin aynı olup olmadığını kontrol etmenin doğru döneceği anlamına gelir ( C-Pyhon , bildiğim kadarıyla bu bir uygulama ayrıntısıdır ), oysa daha büyük sayılar bu yalnızca bir nesne diğerinden başlatılırsa doğru döndürür.

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

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

> a = b
> a
280
> a is b
True

python3.6: a = 98765; b = 98765; a, b => Doğru. Görünüşe göre bir şeyler değişti.
Mikhail Kalaşnikof

@MikhailKalashnikov Hayır. Python 3.6.2'de test ettim, bu hala var.
nix

hala python 3.7.7'de var
Bill Huang


2

Bu docs.python.org'dan: "Her nesnenin bir kimliği, bir türü ve bir değeri vardır. Bir nesnenin kimliği bir kez oluşturulduktan sonra asla değişmez; onu nesnenin bellekteki adresi olarak düşünebilirsiniz." İs "operatörü iki nesnenin kimliğini karşılaştırır; id () işlevi, kimliğini temsil eden bir tamsayı döndürür. "

Görünüşe göre, değeri her değiştirdiğinizde, nesne, kimlik değişikliğinin gösterdiği gibi yeniden oluşturulur. X = 3 ve ardından x = 3.14 satırı hata vermez ve x için farklı kimlikler, türler ve değerler verir.


1
Mükemmel doktor yakalaması.
prosti

xa, adı tanımlayıcı bir nesne , bir ile değer arasında 3değil, bir nesnenin kendisi. Eğer ne zaman x=3.14, sen değişmedi nesneyi önceden tespit edilmiş x- hangi değişti nesne adı x atıfta bulundu.
ArtOfWarfare
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.