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 d
ini 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 -mtimeit
sangat membantu - ini bukan hanya tentang menyelamatkan seratus nanodetik di sana-sini! -)
has_key
tampaknya 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 dict
diperkenalkan).
Ada satu contoh di mana in
sebenarnya membunuh kinerja Anda.
Jika Anda menggunakan in
pada wadah O (1) yang hanya mengimplementasikan __getitem__
dan has_key()
tetapi tidak, __contains__
Anda akan mengubah pencarian O (1) menjadi pencarian O (N) (seperti in
jatuh 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_key
adalah metode kamus, tetapi in
akan bekerja pada koleksi apa pun, dan bahkan ketika __contains__
hilang, in
akan menggunakan metode lain untuk mengulangi koleksi untuk mengetahuinya.
in
tes pada range
objek. Saya tidak begitu yakin tentang efisiensinya pada Python 2 xrange
. ;)
__contains__
dapat dengan mudah menghitung apakah suatu nilai berada dalam kisaran atau tidak.
range
instance 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 True
jika ew
referensi nilai juga merupakan kunci dalam kamus. key not in t
kembali True
jika nilainya tidak ada dalam kamus. Apalagi key = ew
alias sangat, sangat berlebihan. Ejaan yang benar adalah if ew in t
. Itulah jawaban yang diterima dari 8 tahun sebelumnya yang sudah Anda katakan.