Zastanawiam się, co lepiej zrobić:
d = {'a': 1, 'b': 2}
'a' in d
True
lub:
d = {'a': 1, 'b': 2}
d.has_key('a')
True
python
dictionary
igorgue
źródło
źródło
keys()
jest tylko zestawem widoków na słownik, a nie na kopie, podobnie jakx in d.keys()
O (1). Mimox in d
to jest bardziej Python.x in d.keys()
musi skonstruować i zniszczyć obiekt tymczasowy, wraz z przydziałem pamięci, który pociąga za sobą, w którymx in d.keys()
po prostu wykonuje operację arytmetyczną (obliczanie skrótu) i wykonuje wyszukiwanie. Zauważ, żed.keys()
jest to tylko około 10 razy dłużej niż to, co tak naprawdę nie jest długie. Nie sprawdziłem, ale wciąż jestem pewien, że to tylko O (1).in
wygrywa wręcz, nie tylko w elegancji (i nie jest przestarzały ;-), ale także w wydajności, np .:Chociaż poniższe obserwacje nie zawsze są prawdziwe, zauważysz, że zwykle w Pythonie szybsze rozwiązanie jest bardziej eleganckie i Pythoniczne; dlatego
-mtimeit
jest tak pomocny - nie chodzi tylko o zaoszczędzenie setek nanosekund tu i tam! -)źródło
has_key
wydaje się być również O (1).Według dokumentów Pythona :
źródło
has_key()
jest teraz usunięty w Python 3Użyj
dict.has_key()
jeśli (i tylko jeśli) twój kod musi być uruchamiany przez wersje Pythona wcześniejsze niż 2.3 (kiedykey in dict
został wprowadzony).źródło
Jest jeden przykład, w którym
in
faktycznie zabija twoją wydajność.Jeśli używasz
in
w czasie O (1) pojemnik, że tylko narzędzia__getitem__
ihas_key()
ale nie__contains__
można włączyć O (1) szukaj w O (N) wyszukiwania (jakin
wraca do wyszukiwania poprzez liniowy__getitem__
).Naprawienie jest oczywiście trywialne:
źródło
has_key()
jest specyficzny dla słowników Python 2 .in
/__contains__
to właściwy interfejs API do użycia; dla tych pojemników w których pełne skanowanie jest nieuniknione, nie jesthas_key()
metoda i tak , a jeśli nie jest O (1) Podejście wtedy będzie use-case specyficzny i tak aż do dewelopera, aby wybrać odpowiedni typ danych dla tego problemu.has_key
jest metodą słownikową, alein
będzie działać na dowolnej kolekcji, a nawet gdy jej__contains__
brakuje,in
użyje dowolnej innej metody, aby iterować kolekcję, aby się dowiedzieć.źródło
in
testów narange
obiektach jest dość wydajne . Nie jestem jednak pewien jego wydajności w Pythonie 2xrange
. ;)__contains__
Potrafi w prosty sposób obliczyć, czy wartość mieści się w zakresie, czy nie.range
instancji za każdym razem. Używając jednej, istniejącej wcześniej instancji, test „liczby całkowitej w zakresie” jest o około 40% szybszy w moich momentach.Rozwiązanie dict.has_key () jest przestarzałe, użyj „in” - wysublimowanego edytora tekstu 3
Tutaj wziąłem przykład słownika o nazwie „wiek” -
źródło
Rozszerzanie testów wydajności Alexa Martellego o komentarze Adama Parkina ...
źródło
Jeśli masz coś takiego:
zmień go poniżej, aby uruchomić na Pythonie 3.X i nowszych:
źródło
t.has_key(ew)
zwraca,True
jeśliew
odwołania do wartości są również kluczem w słowniku.key not in t
zwraca,True
jeśli wartości nie ma w słowniku. Co więcej,key = ew
alias jest bardzo, bardzo zbędny. Prawidłowa pisownia toif ew in t
. Tak powiedziała już zaakceptowana odpowiedź sprzed 8 lat.