Jawaban:
in jelas lebih pythonic.
keys()hanya tampilan seperti set ke kamus daripada salinan, begitu x in d.keys()juga O (1). Tetap saja, x in dini lebih Pythonic.
x in d.keys()harus membangun dan menghancurkan objek sementara, lengkap dengan alokasi memori yang menyertainya, di mana x in d.keys()hanya melakukan operasi aritmatika (menghitung hash) dan melakukan pencarian. Perhatikan bahwa d.keys()hanya sekitar 10 kali selama ini, yang masih belum terlalu lama. Saya belum memeriksa tetapi saya masih cukup yakin itu hanya O (1).
in menang dengan mudah, tidak hanya dalam keanggunan (dan tidak ditinggalkan ;-) tetapi juga dalam kinerja, misalnya:
$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop
Meskipun pengamatan berikut tidak selalu benar, Anda akan melihat bahwa biasanya , dalam Python, solusi yang lebih cepat lebih elegan dan Pythonic; itu sebabnya -mtimeitsangat membantu - ini bukan hanya tentang menyelamatkan seratus nanodetik di sana-sini! -)
has_keytampaknya juga O (1).
Menurut python docs :
has_key()tidak digunakan lagikey in d.
has_key()sekarang dihapus dengan Python 3
Gunakan dict.has_key()jika (dan hanya jika) kode Anda harus dapat dijalankan oleh versi Python lebih awal dari 2.3 (saat key in dictdiperkenalkan).
Ada satu contoh di mana in sebenarnya membunuh kinerja Anda.
Jika Anda menggunakan inpada wadah O (1) yang hanya mengimplementasikan __getitem__dan has_key()tetapi tidak, __contains__Anda akan mengubah pencarian O (1) menjadi pencarian O (N) (seperti injatuh kembali ke pencarian linear melalui__getitem__ ).
Perbaikan jelas sepele:
def __contains__(self, x):
return self.has_key(x)
has_key()adalah khusus untuk Python 2 kamus . in/ __contains__adalah API yang benar untuk digunakan; bagi mereka wadah di mana scan penuh tidak dapat dihindari tidak ada has_key()metode pula , dan jika ada O a (1) pendekatan maka yang akan digunakan-kasus tertentu dan begitu sampai pengembang untuk memilih tipe data yang tepat untuk masalah tersebut.
has_keyadalah metode kamus, tetapi inakan bekerja pada koleksi apa pun, dan bahkan ketika __contains__hilang, inakan menggunakan metode lain untuk mengulangi koleksi untuk mengetahuinya.
intes pada rangeobjek. Saya tidak begitu yakin tentang efisiensinya pada Python 2 xrange. ;)
__contains__dapat dengan mudah menghitung apakah suatu nilai berada dalam kisaran atau tidak.
rangeinstance baru setiap kali. Dengan menggunakan contoh tunggal, yang sudah ada sebelumnya , tes "integer in range" sekitar 40% lebih cepat dalam timing saya.
Solusi untuk dict.has_key () sudah tidak digunakan lagi, gunakan 'in' - editor teks luhur 3
Di sini saya telah mengambil contoh kamus bernama 'age' -
ages = {}
# Add a couple of names to the dictionary
ages['Sue'] = 23
ages['Peter'] = 19
ages['Andrew'] = 78
ages['Karren'] = 45
# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:
print "Sue is in the dictionary. She is", ages['Sue'], "years old"
else:
print "Sue is not in the dictionary"
Memperluas tes kinerja Alex Martelli dengan komentar Adam Parkin ...
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
x = t.timeit(number)
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'
$ python2.7 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop
$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop
Jika Anda memiliki sesuatu seperti ini:
t.has_key(ew)
ubah ke bawah untuk berjalan di Python 3.X ke atas:
key = ew
if key not in t
t.has_key(ew)kembali Truejika ewreferensi nilai juga merupakan kunci dalam kamus. key not in tkembali Truejika nilainya tidak ada dalam kamus. Apalagi key = ewalias sangat, sangat berlebihan. Ejaan yang benar adalah if ew in t. Itulah jawaban yang diterima dari 8 tahun sebelumnya yang sudah Anda katakan.