Zakładając, że connectionDetails
jest słownikiem Python, jaki jest najlepszy, najbardziej elegancki, najbardziej „pythoniczny” sposób refaktoryzacji kodu w ten sposób?
if "host" in connectionDetails:
host = connectionDetails["host"]
else:
host = someDefaultValue
python
dictionary
coding-style
mnowotka
źródło
źródło
if/else
jest znacznie szybszy. To może, ale nie musi, odgrywać pewną rolę.if/else
jest szybszy?Możesz także użyć
defaultdict
podobnego:Możesz przekazać dowolną zwykłą funkcję zamiast lambda:
źródło
get
ani podobnych metod.Chociaż
.get()
jest ładnym idiomem, jest wolniejszy niżif/else
(i wolniejszy niż,try/except
jeśli przez większość czasu można oczekiwać obecności klucza w słowniku):źródło
if/then
byłoby szybciej. Oba przypadki wymagają przeszukiwania słownika, a jeśli wywoływanieget()
jest o wiele wolniejsze, co jeszcze tłumaczy spowolnienie?O(1)
niezależne od wielkości słownika, więc narzut związany z wywołaniem funkcji jest istotny.W przypadku wielu różnych ustawień domyślnych spróbuj tego:
źródło
None
parametr connectionDetails lub parametr emptyString jako jedna z wartości w parach klucz-wartość. Wdefaults
słowniku potencjalnie jedna z jego wartości może zostać przypadkowo wygaszona. (patrz także stackoverflow.com/questions/6354436 )W słownikach Pythona istnieje taka metoda:
dict.setdefault
Jednak metoda ta ustawia wartość
connectionDetails['host']
, abysomeDefaultValue
jeśli kluczhost
nie jest już zdefiniowane, w przeciwieństwie do tego, co zadał pytanie.źródło
setdefault()
wartość zwrotów, tak to działa, jak również:host = connectionDetails.setdefault('host', someDefaultValue)
. Tylko uważaj, że ustawiconnectionDetails['host']
wartość domyślną, jeśli klucz nie był wcześniej.(to późna odpowiedź)
Alternatywą jest podklasę
dict
klasy i implementację__missing__()
metody w następujący sposób:Przykłady:
źródło
Testując podejrzenia @ Tima Pietzckera dotyczące sytuacji w PyPy (5.2.0-alpha0) dla Pythona 3.3.5, stwierdzam, że rzeczywiście oba sposoby
.get()
iif
/ ielse
działają podobnie. Właściwie wydaje się, że w przypadku if / else jest nawet tylko jedno wyszukiwanie, jeśli warunek i przypisanie dotyczą tego samego klucza (porównaj z ostatnim przypadkiem, w którym są dwa wyszukiwania).źródło
Możesz użyć do tego funkcji Lamba jako jednej linijki. Utwórz nowy obiekt, do
connectionDetails2
którego dostęp jest uzyskiwany jak funkcja ...Teraz użyj
zamiast
która zwraca wartość słownika, jeśli
k
jest w kluczach, w przeciwnym razie zwraca"DEFAULT"
źródło