Chciałem sprawdzić, czy klucz istnieje w słowniku przed zaktualizowaniem wartości klucza. Napisałem następujący kod:
if 'key1' in dict.keys():
print "blah"
else:
print "boo"
Myślę, że nie jest to najlepszy sposób na wykonanie tego zadania. Czy jest lepszy sposób na sprawdzenie klucza w słowniku?
python
dictionary
Mohan Gulati
źródło
źródło
dict.keys()
tworzy listę kluczy, zgodnie z dokumentacją docs.python.org/2/library/stdtypes.html#dict.keys, ale zdziwiłbym się, gdyby ten wzorzec nie został zoptymalizowany pod kątem poważnej implementacji do przetłumaczenia doif 'key1' in dict:
.x in dict.keys()
do sprawdzania kluczy. I tak się stało, ponieważ zwykły sposób iteracyjne nad klucze w Javie jestfor (Type k : dict.keySet())
to zwyczaj powodującfor k in dict.keys()
do czujesz się bardziej naturalnie niżfor k in dict
(co powinno być w porządku pod względem wydajności?), ale potem staje sięif k in dict.keys()
również sprawdzanie kluczy , co jest problemem ...if k in dict_:
sprawdza obecność k w KLUCZACH dict_, więc nadal nie potrzebujeszdict_.keys()
. (To mnie ugryzło, ponieważ czytało mi się, jakby testowało wartość w dyktando. Ale tak nie jest.)Odpowiedzi:
in
jest zamierzonym sposobem sprawdzenia istnienia klucza w plikudict
.Jeśli chcesz mieć wartość domyślną, zawsze możesz użyć
dict.get()
:a jeśli chcesz zawsze zapewnić domyślną wartość dla dowolnego klucza, którego możesz użyć
dict.setdefault()
wielokrotnie lubdefaultdict
zcollections
modułu, na przykład:ale ogólnie
in
słowo kluczowe jest najlepszym sposobem na to.źródło
get
jeśli i tak będę wyciągać element ze słownika. Nie ma sensu używaćin
i wyciągać elementu ze słownika.in
to najlepszy sposób na zrobienie tego.0
na przykład. Nauczyłem się tego naNie musisz dzwonić na klucze:
Będzie to znacznie szybsze, ponieważ używa haszowania słownika w przeciwieństwie do wyszukiwania liniowego, co robiłyby klawisze wywoływania.
źródło
if key in d1
zajęło mi0.17265701293945312
kilka sekund. Powołanieif key in d1.keys()
trwało0.23871088027954102
- to klasyczna definicja mikro optymalizacji. Oszczędzanie0.07884883880615234
sekund nie zwiększa wydajności.keys()
daje 0,01 sekundy korzyści obliczeniowej. Za ~ 500 000 kluczy, brak połączeniakeys()
daje 1 sekundę korzyści. Dla ~ 5 000 000 kluczy, brak połączeniakeys()
jest o 0,4 sekundy szybszy, ale dla 50 000 000 kluczy WYWOŁANIEkeys()
JEST 3 SEKUNDY SZYBCIEJ!Możesz sprawdzić obecność klucza w słowniku, używając słowa kluczowego in :
Typowym zastosowaniem do sprawdzania istnienia klucza w słowniku przed jego mutacją jest domyślna inicjalizacja wartości (np. Jeśli twoje wartości są na przykład listami i chcesz upewnić się, że istnieje pusta lista, do której możesz dołączyć podczas wstawiania pierwszej wartości klucza). W takich przypadkach może okazać się interesujący
collections.defaultdict()
typ.W starszym kodzie można również znaleźć niektóre zastosowania
has_key()
przestarzałej metody sprawdzania istnienia kluczy w słownikach (wystarczy użyćkey_name in dict_name
zamiast tego).źródło
key in dict.keys()
. Spróbuj usunąć cały kod z wyjątkiem tej kontroli i sprawdź, jaki jest twój wynik.Możesz to skrócić:
Jest to jednak w najlepszym przypadku kosmetyczna poprawa. Dlaczego uważasz, że to nie jest najlepszy sposób?
źródło
Aby uzyskać dodatkowe informacje na temat szybkości wykonywania proponowanych metod przyjętej odpowiedzi (pętle 10 m):
'key' in mydict
czas, który upłynął 1,07 sekmydict.get('key')
czas, który upłynął 1,84 sekmydefaultdict['key']
czas, który upłynął 1,07 sekDlatego przy użyciu
in
lubdefaultdict
są zalecane przeciwkoget
.źródło
get
1,84 to <1,07 * 2 ;-Psetdefault
Zamiast tego poleciłbym użycie tej metody. Wygląda na to, że zrobi wszystko, co chcesz.źródło
setdefault
ma wspólnego z pytaniem PO?Słownik w Pythonie ma metodę get ('key', domyślnie). Możesz więc ustawić wartość domyślną na wypadek, gdyby nie było klucza.
źródło
Co z użyciem EAFP (łatwiej poprosić o wybaczenie niż zgodę):
Zobacz inne posty SO:
Używanie try vs, jeśli w Pythonie lub
Sprawdzanie istnienia członka w Pythonie
źródło
Za pomocą operatora trójskładnikowego:
źródło
Sposoby uzyskania wyników to:
To, co jest lepsze, zależy od 3 rzeczy:
Czytaj więcej: http://paltman.com/try-except-performance-in-python-a-simple-test/
Użycie try / block zamiast „in” lub „if”:
źródło
2to3
i zauważyłem, że składnia bez try jest zawsze szybsza niż składnia z try, nawet w przypadku, gdy klucz znajduje się w dykcie.Tylko Python 2: (i Python 2.7
in
już obsługuje )możesz użyć metody has_key ():
źródło
.has_key()
został uznany za przestarzały ; powinieneś używać,in
jak pokazano w innych odpowiedziach.Tylko dodatkowa informacja dla Chrisa. B (najlepsza odpowiedź):
Działa również; Powodem jest to, że wywoływanie
int()
zwraca0
to, codefaultdict
robi za kulisami (podczas konstruowania słownika), stąd nazwa „Funkcja fabryczna” w dokumentacji.źródło
defaultdict(lambda: 0)
zamiast tego,defaultdict(int)
ponieważ myślę, że jest bardziej zrozumiałe, co się dzieje; czytelnik nie musi wiedzieć, że dostajesz,0
jeśli dzwoniszint()
bez argumentów. YMMV.Aby dowiedzieć się, jak to zrobić, najpierw sprawdzamy, jakie metody możemy wywołać w słowniku. Oto metody:
Brutalna metoda sprawdzenia, czy klucz już istnieje, może być następującą
get()
metodą:Pozostałe dwie interesujące metody
items()
ikeys()
brzmią jak zbyt dużo pracy. Sprawdźmy więc, czyget()
jest to dla nas właściwa metoda. Mamy nasz dyktandd
:Drukowanie pokazuje, że klucz, którego nie mamy, powróci
None
:My
możeużywać, aby uzyskać informacje, czy klucz jest obecny lub nie. Ale rozważ to, jeśli utworzymy dyktat z jednymkey:None
:Prowadzenie tej
get()
metody nie jest wiarygodne w przypadku, gdy niektóre wartości mogą byćNone
. Ta historia powinna mieć szczęśliwsze zakończenie. Jeśli użyjemyin
komparatora:Otrzymujemy prawidłowe wyniki. Możemy zbadać kod bajtowy Pythona:
To pokazuje, że
in
operator porównania jest nie tylko bardziej niezawodny, ale nawet szybszy niżget()
.źródło
.get()
może mieć drugi argumentdefault
wartości, który może być wykorzystany do rozwiązania problemu gdziekey:None
. przykład:d.get("key", False)
.get()
to najszybszy sposób. Inną opcją jest przypisanie w blokutry
/except
Słownik Python ma metodę o nazwie
__contains__
. Ta metoda zwróci True, jeśli słownik ma klucz, a inna zwróci False.źródło
__contains__
. Prawidłowym sposobem na to jest użyciein
operatora, którycontainment check
wywołuje__contains__
funkcję.foo = x['foo'] if x.__contains__('foo') else 'bar'
. Wszelkie pomysły, w jaki sposób można użyćin
operatora jako części tego wyrażenia?foo = x['foo'] if 'foo' in x else 'bar'
Udostępnianie jeszcze jednego sposobu sprawdzania, czy klucz istnieje za pomocą operatorów logicznych.
To zwraca
Wyjaśnienie
Po pierwsze należy wiedzieć, że w Pythonie
0
,None
lub obiektów o zerowej długości do ocenyFalse
. Wszystko inne oceniaTrue
. Operacje logiczne są oceniane od lewej do prawej i zwracają operand nie Prawda lub Fałsz.Zobaczmy przykład:
Ponieważ
'Some string'
ocenia naTrue
, resztaor
nie jest oceniana i nie występuje podział przez błąd zerowy.Ale jeśli zmienimy,
1/0
najpierw oceniane jest zamówienie i pojawia się wyjątek:Możemy użyć tego do wzorca do sprawdzenia, czy klucz istnieje.
robi to samo co
To już zwraca poprawny wynik, jeśli klucz istnieje, ale chcemy, aby wypisał „boo”, gdy nie istnieje. Tak więc bierzemy wynik i
or
to z'boo'
źródło
Możesz użyć
for
pętli do iteracji w słowniku i uzyskać nazwę klucza, który chcesz znaleźć w słowniku, a następnie sprawdź, czy istnieje, czy nie używaif
warunku:źródło
it is exist
inot exist