Jawaban:
Seperti ini:
host = connectionDetails.get('host', someDefaultValue)
if/elsejauh lebih cepat. Itu mungkin atau mungkin tidak berperan.
if/elselebih cepat?
Anda juga dapat menggunakan defaultdictseperti ini:
from collections import defaultdict
a = defaultdict(lambda: "default", key="some_value")
a["blabla"] => "default"
a["key"] => "some_value"
Anda dapat melewati fungsi biasa alih-alih lambda:
from collections import defaultdict
def a():
return 4
b = defaultdict(a, key="some_value")
b['absent'] => 4
b['key'] => "some_value"
getatau metode serupa.
Meskipun .get()ini adalah ungkapan yang bagus, ini lebih lambat daripada if/else(dan lebih lambat daripada try/exceptjika kehadiran kunci dalam kamus dapat diharapkan sebagian besar waktu):
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="try:\n a=d[1]\nexcept KeyError:\n a=10")
0.07691968797894333
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="try:\n a=d[2]\nexcept KeyError:\n a=10")
0.4583777282275605
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="a=d.get(1, 10)")
0.17784020746671558
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="a=d.get(2, 10)")
0.17952161730158878
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="if 1 in d:\n a=d[1]\nelse:\n a=10")
0.10071221458065338
>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
... stmt="if 2 in d:\n a=d[2]\nelse:\n a=10")
0.06966537335119938
if/then akan lebih cepat. Kedua kasus memerlukan lookup kamus, dan kecuali seruan get()ini begitu jauh lebih lambat, apa account lain untuk perlambatan?
O(1)terlepas dari ukuran kamus, sehingga overhead panggilan fungsi relevan.
Untuk beberapa standar yang berbeda coba ini:
connectionDetails = { "host": "www.example.com" }
defaults = { "host": "127.0.0.1", "port": 8080 }
completeDetails = {}
completeDetails.update(defaults)
completeDetails.update(connectionDetails)
completeDetails["host"] # ==> "www.example.com"
completeDetails["port"] # ==> 8080
Noneatau BlankString sebagai salah satu nilai dalam pasangan nilai kunci. The defaultskamus berpotensi memiliki salah satu dari nilai-nilai tidak sengaja blanked keluar. (lihat juga stackoverflow.com/questions/6354436 )
Ada metode dalam kamus python untuk melakukan ini: dict.setdefault
connectionDetails.setdefault('host',someDefaultValue)
host = connectionDetails['host']
Namun metode ini menetapkan nilai connectionDetails['host']untuk someDefaultValuejika kunci hostbelum ditentukan, tidak seperti apa pertanyaan yang diajukan.
setdefault()nilai pengembalian, jadi ini bekerja dengan baik: host = connectionDetails.setdefault('host', someDefaultValue). Berhati-hatilah karena akan disetel connectionDetails['host']ke nilai default jika kunci tidak ada di sana sebelumnya.
(ini jawaban yang terlambat)
Alternatifnya adalah dengan subkelas dictkelas dan mengimplementasikan __missing__()metode, seperti ini:
class ConnectionDetails(dict):
def __missing__(self, key):
if key == 'host':
return "localhost"
raise KeyError(key)
Contoh:
>>> connection_details = ConnectionDetails(port=80)
>>> connection_details['host']
'localhost'
>>> connection_details['port']
80
>>> connection_details['password']
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 6, in __missing__
KeyError: 'password'
Menguji kecurigaan @Tim Pietzcker tentang situasi di PyPy (5.2.0-alpha0) untuk Python 3.3.5, saya menemukan bahwa memang keduanya .get()dan if/ elsecara melakukan yang serupa. Sebenarnya sepertinya dalam kasus if / else bahkan hanya ada satu pencarian jika kondisi dan tugas melibatkan kunci yang sama (bandingkan dengan kasus terakhir di mana ada dua pencarian).
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="try:\n a=d[1]\nexcept KeyError:\n a=10")
0.011889292989508249
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="try:\n a=d[2]\nexcept KeyError:\n a=10")
0.07310474599944428
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="a=d.get(1, 10)")
0.010391917996457778
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="a=d.get(2, 10)")
0.009348208011942916
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="if 1 in d:\n a=d[1]\nelse:\n a=10")
0.011475925013655797
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="if 2 in d:\n a=d[2]\nelse:\n a=10")
0.009605801998986863
>>>> timeit.timeit(setup="d={1:2, 3:4, 5:6, 7:8, 9:0}",
.... stmt="if 2 in d:\n a=d[2]\nelse:\n a=d[1]")
0.017342638995614834
Anda dapat menggunakan fungsi lamba untuk ini sebagai satu-liner. Buat objek baru connectionDetails2yang diakses seperti fungsi ...
connectionDetails2 = lambda k: connectionDetails[k] if k in connectionDetails.keys() else "DEFAULT"
Sekarang gunakan
connectionDetails2(k)
dari pada
connectionDetails[k]
yang mengembalikan nilai kamus jika kada di tombol, jika tidak maka akan kembali"DEFAULT"