Mengapa membandingkan string dengan menggunakan '==' atau 'adalah' kadang-kadang menghasilkan hasil yang berbeda?

I've punya Python program di mana dua variabel-variabel yang ditetapkan untuk nilai 'umum'. Dalam ekspresi kondisional saya memiliki perbandingan var1 adalah var2 yang gagal, tapi jika saya mengubah itu untuk var1 == var2 mengembalikan True.

Sekarang jika saya membuka saya interpreter Python dan melakukan hal yang sama "adalah" perbandingan, itu berhasil.

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

Apa yang saya hilang di sini?

Mengomentari pertanyaan (7)
Larutan

ini adalah identitas pengujian, == kesetaraan pengujian. apa yang terjadi dalam kode anda akan ditiru di penerjemah seperti ini:

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

jadi, tidak heran mereka're tidak sama, kan?

Dengan kata lain: ini adalah id(a) == id(b)

Komentar (12)

Jawaban lainnya berikut adalah benar: adalah digunakan untuk identitas perbandingan, sementara == digunakan untuk kesetaraan perbandingan. Karena apa yang anda pedulikan adalah kesetaraan (dua string harus berisi karakter yang sama), dalam hal ini adalah operator adalah hanya salah dan anda harus menggunakan == sebagai gantinya.

Alasan adalah bekerja secara interaktif adalah yang (paling) string literal adalah magang secara default. Dari Wikipedia:

Magang string mempercepat string perbandingan, yang kadang-kadang hambatan kinerja dalam aplikasi (seperti compiler dan dinamis programming language runtime) yang sangat bergantung pada tabel hash dengan string kunci. Tanpa magang, memeriksa bahwa dua senar yang berbeda adalah sama melibatkan memeriksa setiap karakter dari kedua string. Ini adalah lambat karena beberapa alasan: hal ini inheren O(n) panjang string; biasanya membutuhkan membaca dari beberapa daerah di memori, yang waktu; dan berbunyi mengisi processor cache, berarti ada yang kurang cache tersedia untuk kebutuhan yang lain. Dengan magang string, objek sederhana identitas tes sudah cukup setelah asli magang operasi; ini adalah biasanya diimplementasikan sebagai pointer kesetaraan tes, biasanya hanya satu mesin instruksi dengan memori tidak ada referensi sama sekali.

Jadi, ketika anda memiliki dua string literal (kata-kata yang secara harfiah yang diketikkan ke dalam program source code, dikelilingi oleh tanda kutip) dalam program yang memiliki nilai yang sama, Python compiler akan secara otomatis magang string, membuat mereka berdua disimpan pada lokasi memori. (Catatan bahwa ini doesn't selalu terjadi, dan aturan untuk ketika ini terjadi cukup berbelit-belit, jadi silakan don't bergantung pada perilaku ini dalam kode produksi!)

Sejak dalam sesi interaktif kedua string adalah benar-benar disimpan dalam lokasi memori yang sama, mereka memiliki hak yang sama identitas, sehingga adalah operator bekerja seperti yang diharapkan. Tapi jika anda membangun sebuah string dengan beberapa metode lain (bahkan jika string yang berisi persis karakter yang sama), maka string yang mungkin sama, tapi itu tidak string yang sama - yaitu, ia memiliki yang berbeda identitas, karena disimpan di tempat yang berbeda dalam memori.

Komentar (8)

The adalah kata kunci adalah tes untuk objek identitas sementara == adalah nilai perbandingan.

Jika anda menggunakan adalah, hasilnya akan true jika dan hanya jika objek adalah objek yang sama. Namun, == akan menjadi kenyataan suatu saat nilai-nilai dari objek yang sama.

Komentar (0)

Satu hal terakhir yang perlu diperhatikan, anda bisa menggunakan intern berfungsi untuk memastikan bahwa anda're mendapatkan referensi untuk string yang sama:

>>> a = intern('a')
>>> a2 = intern('a')
>>> a is a2
True

Seperti yang ditunjukkan di atas, anda mungkin harus tidak lakukan adalah untuk menentukan kesetaraan pada string. Tapi ini dapat membantu untuk mengetahui jika anda memiliki beberapa jenis aneh persyaratan untuk menggunakan adalah.

Perhatikan bahwa magang fungsi harus pindah dari yang dibangun di fungsi untuk berada di modul sys untuk Python 3.

Komentar (0)

ini adalah identitas pengujian, == kesetaraan pengujian. Apa ini berarti adalah bahwa ini adalah cara untuk memeriksa apakah dua hal yang sama hal-hal, atau hanya setara.

Katakanlah anda've got sederhana orang objek. Jika hal ini yang bernama 'Jack' dan '23' tahun old, it's setara dengan yang lain 23yr tua Jack, tapi bukan orang yang sama.

class Person(object):
   def __init__(self, name, age):
       self.name = name
       self.age = age

   def __eq__(self, other):
       return self.name == other.name and self.age == other.age

jack1 = Person('Jack', 23)
jack2 = Person('Jack', 23)

jack1 == jack2 #True
jack1 is jack2 #False

Mereka're usia yang sama, tapi mereka're tidak contoh sama orang. String mungkin setara dengan yang lain, tapi itu's tidak objek yang sama.

Komentar (0)

Ini adalah catatan samping, tapi di idiomatik python, anda akan sering melihat hal-hal seperti:

if x is None: 
    # some clauses

Ini adalah aman, karena ada jaminan untuk menjadi salah satu contoh Null Objek (yaitu, Tidak ada).

Komentar (3)

Jika anda're tidak yakin apa yang anda're lakukan, gunakan '=='. Jika anda memiliki sedikit lebih banyak pengetahuan tentang hal itu anda dapat menggunakan 'adalah' untuk diketahui benda-benda seperti 'Ada'.

Jika tidak, anda'll akhirnya bertanya-tanya mengapa hal-hal yang doesn't bekerja dan mengapa hal ini terjadi:

>>> a = 1
>>> b = 1
>>> b is a
True
>>> a = 6000
>>> b = 6000
>>> b is a
False

I'm bahkan tidak yakin jika ada hal-hal yang dijamin untuk tetap sama antara berbagai versi python/implementasi.

Komentar (4)

Dari pengalaman saya yang terbatas dengan python, adalah ini digunakan untuk membandingkan dua benda untuk melihat jika mereka adalah objek yang sama sebagai lawan dua objek yang berbeda dengan nilai yang sama. == digunakan untuk menentukan apakah nilai-nilai yang identik.

Berikut adalah contoh yang baik:

>>> s1 = u'public'
>>> s2 = 'public'
>>> s1 is s2
False
>>> s1 == s2
True

s1 adalah unicode string, dan s2 adalah string yang normal. Mereka bukan jenis yang sama, tetapi nilai yang sama.

Komentar (1)

Saya pikir itu ada hubungannya dengan fakta bahwa, ketika 'adalah' perbandingan mengevaluasi ke false, dua objek yang berbeda yang digunakan. Jika mengevaluasi ke true, yang berarti secara internal itu's menggunakan obyek yang sama persis dan tidak membuat yang baru, mungkin karena anda membuat mereka hanya sebagian kecil dari 2 detik atau lebih dan karena ada isn't kesenjangan waktu yang besar di antara it's dioptimalkan dan menggunakan objek yang sama.

Ini adalah mengapa anda harus menggunakan kesetaraan operator ==, bukan adalah, untuk membandingkan nilai dari sebuah objek string.

>>> s = 'one'
>>> s2 = 'two'
>>> s is s2
False
>>> s2 = s2.replace('two', 'one')
>>> s2
'one'
>>> s2 is s
False
>>> 

Dalam contoh ini, saya membuat s2, yang berbeda string objek yang sebelumnya sama dengan 'satu' tapi itu bukan objek yang sama sebagai s, karena penerjemah tidak menggunakan objek yang sama seperti yang saya awalnya tidak menetapkan ke 'satu', jika aku punya itu akan membuat mereka objek yang sama.

Komentar (2)

Saya percaya bahwa ini adalah yang dikenal sebagai "magang" strings. Python ini, begitu juga Jawa, dan begitu C dan C++ ketika menyusun dioptimalkan mode.

Jika anda menggunakan dua identik string, daripada membuang-buang memori dengan membuat dua objek string, semua yang ditahan string dengan isi yang sama menunjuk ke memori yang sama.

Ini hasil dalam Python "adalah" operator kembali Benar karena dua string dengan isi yang sama yang menunjuk pada objek string. Ini juga akan terjadi di pulau Jawa dan di C.

Ini hanya berguna untuk memori tabungan sekalipun. Anda tidak dapat bergantung pada itu untuk menguji kesetaraan string, karena berbagai interpreter dan compiler dan JIT mesin tidak selalu melakukannya.

Komentar (0)

Saya menjawab pertanyaan meskipun pertanyaan ini adalah untuk lama karena tidak ada jawaban atas kutipan referensi bahasa

Sebenarnya adalah operator memeriksa identitas dan == operator memeriksa kesetaraan,

Dari Bahasa Referensi:

Jenis mempengaruhi hampir semua aspek dari objek perilaku. Bahkan pentingnya identitas objek dipengaruhi dalam beberapa rasa: untuk berubah jenis, operasi yang menghitung nilai-nilai baru benar-benar dapat mengembalikan referensi ke setiap ada objek dengan jenis yang sama dan nilai, sedangkan untuk benda-benda yang bisa berubah ini tidak diperbolehkan. E. g., setelah a = 1; b = 1, a dan b mungkin atau mungkin tidak mengacu pada objek yang sama dengan nilai satu, tergantung pada pelaksanaan, tapi setelah c = []; d = [], c dan d yang dijamin untuk merujuk kepada dua hal yang berbeda, unik, baru dibuat daftar kosong. (Perhatikan bahwa c = d = [] menetapkan objek yang sama untuk kedua c dan d.)

jadi dari pernyataan diatas kita dapat menyimpulkan bahwa string yang berubah jenis mungkin gagal ketika diperiksa dengan "adalah" dan dapat diperiksa berhasil ketika diperiksa dengan "adalah"

Hal yang sama berlaku untuk int,tuple yang juga berubah jenis

Komentar (0)

The == operator uji nilai kesetaraan. The adalah operator tes identitas objek, Python tes apakah keduanya benar-benar objek yang sama(yaitu, tinggal di alamat yang sama di memori).

>>> a = 'banana'
>>> b = 'banana'
>>> a is b 
True

Dalam contoh ini, Python hanya dibuat satu objek string, dan kedua a dan b mengacu pada itu. Alasannya adalah bahwa Python internal cache dan reuses beberapa string sebagai optimasi, ada benar-benar hanya sebuah string 'pisang' di memori, bersama dengan a dan b; Untuk memicu perilaku normal, anda perlu menggunakan string yang lebih panjang:

>>> a = 'a longer banana'
>>> b = 'a longer banana'
>>> a == b, a is b
(True, False)

Ketika anda membuat dua daftar, anda mendapatkan dua benda:

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

Dalam hal ini kita akan mengatakan bahwa dua daftar yang setara, karena mereka memiliki unsur yang sama, tetapi tidak identik, karena mereka tidak memiliki objek yang sama. Jika dua benda yang identik, mereka juga setara, tetapi jika mereka adalah sama, mereka tidak selalu identik.

Jika a mengacu pada sebuah objek dan anda menetapkan b = a, maka kedua variabel yang mengacu pada objek yang sama:

>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
Komentar (0)

ini akan membandingkan lokasi memori. Hal ini digunakan untuk objek-tingkat perbandingan.

== akan membandingkan variabel-variabel di dalam program. Hal ini digunakan untuk memeriksa di nilai tingkat.

lebih cek untuk alamat tingkat kesetaraan

== cek untuk nilai tingkat kesetaraan

Komentar (0)

ini adalah identitas pengujian, == kesetaraan pengujian (lihat Python Dokumentasi).

Dalam kebanyakan kasus, jika a b, maka a == b. Tapi ada pengecualian, misalnya:

>>> nan = float('nan')
>>> nan is nan
True
>>> nan == nan
False

Jadi, anda hanya dapat menggunakan lebih untuk identitas tes, pernah tes kesetaraan.

Komentar (0)