The
is
operator tidak sesuai dengan nilai-nilai variabel, tetapi kasus itu sendiri.
Apa sebenarnya maksudnya itu?
Saya mendeklarasikan dua variabel bernama x
dan y
menetapkan nilai yang sama di kedua variabel, tetapi mengembalikan false ketika saya menggunakan is
operator.
Saya butuh klarifikasi. Ini kode saya.
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
Jawaban:
Anda salah paham tentang apa yang
is
diuji operator. Ini menguji jika dua variabel menunjuk objek yang sama , bukan jika dua variabel memiliki nilai yang sama.Dari dokumentasi untuk
is
operator :Gunakan
==
operator sebagai gantinya:Ini cetakan
True
.x
dany
dua daftar terpisah :Jika Anda menggunakan
id()
fungsi tersebut, Anda akan melihatnyax
dany
memiliki pengenal yang berbeda:tetapi jika Anda akan menetapkan
y
kex
maka keduanya menunjuk ke objek yang sama:dan
is
menunjukkan keduanya adalah objek yang sama, ia mengembalikanTrue
.Ingatlah bahwa dalam Python, nama hanyalah label yang mereferensikan nilai ; Anda dapat memiliki beberapa nama yang mengarah ke objek yang sama.
is
memberi tahu Anda jika dua nama menunjuk ke satu dan objek yang sama.==
memberi tahu Anda jika dua nama merujuk ke objek yang memiliki nilai yang sama.sumber
A is B
sama saja denganid(A) == id(B)
.id(A)
dalam variabel dan nanti berharapvariable == id(B)
untuk tetap bekerja; jikaA
dihapus sementara itu makaB
bisa saja diberi lokasi memori yang sama.\n
>>> y = 5\n
>>> x adalah y\n
Benar\n
>>> x == y\n
Benar\n
>>>\n
Duplikat lain menanyakan mengapa dua string yang sama umumnya tidak identik, yang sebenarnya tidak dijawab di sini:
Jadi, mengapa mereka tidak memiliki string yang sama? Terutama mengingat ini:
Mari kita tunda bagian kedua sebentar. Bagaimana yang pertama bisa benar?
Penerjemah harus memiliki "tabel interning", tabel yang memetakan nilai string ke objek string, jadi setiap kali Anda mencoba membuat string baru dengan konten
'abc'
, Anda mendapatkan objek yang sama. Wikipedia memiliki diskusi yang lebih rinci tentang cara kerja magang.Dan Python memiliki tabel interning string; Anda bisa memasukkan string internal secara manual dengan
sys.intern
metode ini.Faktanya, Python diizinkan untuk secara otomatis menyimpan tipe yang tidak dapat diubah, tetapi tidak diharuskan untuk melakukannya. Implementasi yang berbeda akan memiliki nilai yang berbeda pula.
CPython (implementasi yang Anda gunakan jika Anda tidak tahu implementasi mana yang Anda gunakan) auto-interns bilangan bulat kecil dan beberapa singlet khusus seperti
False
, tetapi bukan string (atau bilangan bulat besar, atau tupel kecil, atau apa pun). Anda dapat melihat ini dengan mudah:Oke, tapi kenapa
z
danw
identik?Itu bukan interpreter yang secara otomatis melakukan intern, itulah nilai lipat kompilator.
Jika waktu kompilasi yang sama string yang muncul dua kali dalam modul yang sama (apa sebenarnya berarti ini sulit untuk menentukan-itu bukan hal yang sama sebagai literal string yang, karena
r'abc'
,'abc'
dan'a' 'b' 'c'
semua literal berbeda tetapi sama string tetapi mudah dimengerti secara intuitif), kompilator hanya akan membuat satu turunan dari string, dengan dua referensi.Faktanya, kompilator dapat melangkah lebih jauh:
'ab' + 'c'
dapat dikonversi'abc'
oleh pengoptimal, dalam hal ini dapat dilipat bersama dengan'abc'
konstanta dalam modul yang sama.Sekali lagi, ini adalah sesuatu yang diperbolehkan Python tetapi tidak wajib dilakukan. Tetapi dalam kasus ini, CPython selalu melipat string kecil (dan juga, misalnya, tupel kecil). (Meskipun compiler pernyataan-demi-pernyataan interpreter interaktif tidak menjalankan pengoptimalan yang sama seperti compiler module-at-a-time, jadi Anda tidak akan melihat hasil yang persis sama secara interaktif.)
Jadi, apa yang harus Anda lakukan sebagai programmer?
Yah… tidak ada. Anda hampir tidak pernah memiliki alasan untuk peduli jika dua nilai yang tidak dapat diubah itu identik. Jika Anda ingin tahu kapan Anda bisa menggunakan
a is b
alih-aliha == b
, Anda menanyakan pertanyaan yang salah. Selalu gunakana == b
kecuali dalam dua kasus:x is None
.x
akan memengaruhiy
.sumber
w
danz
identik karena nilai lipat kompiler, mengapa ini juga bekerja di REPL, bahkan menggunakanid()
untuk memeriksa referensi? Menggunakan REPL pada Python 3.7is
hanya mengembalikan nilai true jika mereka sebenarnya adalah objek yang sama. Jika mereka sama, perubahan yang satu juga akan muncul di yang lain. Inilah contoh perbedaannya.sumber
Dipicu oleh pertanyaan duplikat , analogi ini mungkin berhasil:
sumber
is
danis not
merupakan dua operator identitas di Python.is
operator tidak membandingkan nilai variabel, tetapi membandingkan identitas variabel. Pertimbangkan ini:Contoh di atas menunjukkan kepada Anda bahwa identitas (bisa juga menjadi alamat memori di Cpython) berbeda untuk keduanya
a
danb
(meskipun nilainya sama). Itulah mengapa ketika Anda mengatakana is b
itu mengembalikan salah karena ketidakcocokan dalam identitas kedua operan. Namun ketika Anda mengatakana == b
, itu mengembalikan true karena==
operasi hanya memverifikasi jika kedua operan memiliki nilai yang sama yang ditetapkan padanya.Contoh menarik (untuk kelas ekstra):
Dalam contoh di atas, meskipun
a
danb
merupakan dua variabel berbeda,a is b
dikembalikanTrue
. Ini karena tipea
isint
yang merupakan objek tetap. Jadi python (saya kira untuk menghemat memori) mengalokasikan objek yang samab
ketika dibuat dengan nilai yang sama. Jadi dalam kasus ini, identitas variabel cocok dana is b
ternyataTrue
.Ini akan berlaku untuk semua objek yang tidak dapat diubah:
Semoga membantu.
sumber
-5
atau lebih tinggi dari256
di Python akan menjadi False. Python menyimpan angka dalam rentang [-5, 256].x is y
sama denganid(x) == id(y)
, membandingkan identitas objek.Seperti yang ditunjukkan @ tomasz-kurgan pada komentar di bawah,
is
operator berperilaku tidak biasa dengan objek tertentu.Misalnya
Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
sumber
Seperti yang Anda lihat di sini ke bilangan bulat kecil. Angka di atas 257 bukanlah int kecil, jadi dihitung sebagai objek yang berbeda.
Lebih baik digunakan
==
sebagai gantinya dalam kasus ini.Informasi lebih lanjut ada di sini: http://docs.python.org/2/c-api/int.html
sumber
X menunjuk ke sebuah larik, Y menunjuk ke larik yang berbeda. Array tersebut identik, tetapi
is
operator akan melihat pointer tersebut, yang tidak identik.sumber
is
fungsionalitas operator menunjukkan ini.id
kecuali Anda memintanya.Ini membandingkan identitas objek, yaitu, apakah variabel merujuk ke objek yang sama dalam memori. Ini seperti
==
di Java atau C (saat membandingkan pointer).sumber
Contoh sederhana dengan buah-buahan
Keluaran:
Jika kamu mencoba
Outputnya berbeda:
Itu karena operator == hanya membandingkan konten variabel. Untuk membandingkan identitas 2 variabel, gunakan operator is
Untuk mencetak nomor identifikasi:
sumber
The
is
Operator hanyalah versi bahasa Inggris dari==
. Karena ID dari kedua list berbeda maka jawabannya salah. Anda dapat mencoba:* Karena ID dari kedua daftar akan sama
sumber
is
bukan 'versi bahasa Inggris==
'