Chcę wstawić parę klucz-wartość do dict, jeśli klucz nie jest w dict.keys (). Zasadniczo mógłbym to zrobić za pomocą:
if key not in d.keys():
d[key] = value
Ale czy jest lepszy sposób? Albo jakie jest pythonowe rozwiązanie tego problemu?
python
dictionary
Xiaochen Cui
źródło
źródło
Odpowiedzi:
Nie musisz więc dzwonić
d.keys()
, więcif key not in d: d[key] = value
wystarczy. Nie ma jaśniejszej, bardziej czytelnej metody.
Możesz zaktualizować ponownie za pomocą
dict.get()
, co zwróci istniejącą wartość, jeśli klucz już istnieje:ale zdecydowanie odradzam; jest to kodowanie w golfa, utrudniające konserwację i czytelność.
źródło
Zastosowanie
dict.setdefault()
:>>> d = {1: 'one'} >>> d.setdefault(1, '1') 'one' >>> d # d has not changed because the key already existed {1: 'one'} >>> d.setdefault(2, 'two') 'two' >>> d {1: 'one', 2: 'two'}
źródło
dict.setdefault()
powinno być używane tylko podczas próby uzyskania dostępu do wartości.setdefault()
wyraźnie opisuje, co się dzieje - to, że zwraca również wartość, nie jest tak ważne, i trochę dziwaczne IMO. Czy mógłbyś podać szybkie wyjaśnienie lub link do takiego, dlaczego nie jest to pożądane?for obj in iterable: d.setdefault(key_for_obj(obj), []).append(obj)
. W zwracanej wartości nie ma nic dziwacznego, o to właśnie chodzi w tej metodzie .if key not in d:
testu.setdefault()
wydaje się być nastawiony na to, co powiedziałeś. Użycie adefaultdict(list)
spowodowałoby, że kod byłby bardziej czytelny niż twój przykład ... więc być może nie ma z niego żadnego pożytku, chyba że trzeba pracować ze standardowymi słownikami. Ogólnieif key not in d
jest jaśniejszy.Od Pythona 3.9 można użyć operatora merge,
|
aby połączyć dwa słowniki. Dykt po prawej ma pierwszeństwo:Na przykład:
new_dict = { 'a': 1, 'b': 2 } | { 'b': 42 } print(new_dict} # {'a': 1, 'b': 42}
Uwaga: tworzy to nowy słownik ze zaktualizowanymi wartościami.
źródło
Za pomocą poniższych możesz wstawić wiele wartości, a także mieć wartości domyślne, ale tworzysz nowy słownik.
Przetestowałem go z największą liczbą głosowanych odpowiedzi i średnio jest to szybsze, jak widać na poniższym przykładzie.
Test szybkości porównujący metodę opartą na pętli for ze zrozumieniem dyktu z metodą operatora rozpakowania.
jeśli kopia (
d = default_vals.copy()
) nie zostanie wykonana w pierwszym przypadku, wówczas odpowiedź z największą liczbą głosów będzie szybsza, gdy osiągniemy rząd wielkości10**5
i więcej. Ślad pamięciowy obu metod jest taki sam.źródło
{**default_values, **{ key: value }}
Zgodnie z powyższymi odpowiedziami zadziałała u mnie metoda setdefault () .
old_attr_name = mydict.setdefault(key, attr_name) if attr_name != old_attr_name: raise RuntimeError(f"Key '{key}' duplication: " f"'{old_attr_name}' and '{attr_name}'.")
Chociaż to rozwiązanie nie jest ogólne. Po prostu pasowało mi do tego konkretnego przypadku. Dokładnym rozwiązaniem byłoby sprawdzenie
key
pierwszego (zgodnie z wcześniejszymi zaleceniami), ale dzięki temusetdefault()
unikamy jednego dodatkowego wyszukiwania w słowniku, to znaczy, choć niewielkiego, ale wciąż zwiększającego wydajność.źródło