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?
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?
Odpowiedzi:
Nie musisz więc dzwonić d.keys()
, więc
if 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:
d[key] = d.get(key, value)
ale zdecydowanie odradzam; jest to kodowanie w golfa, utrudniające konserwację i czytelność.
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'}
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 a defaultdict(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ólnie if 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:
new_dict = old_dict | { key: val }
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.
Za pomocą poniższych możesz wstawić wiele wartości, a także mieć wartości domyślne, ale tworzysz nowy słownik.
d = {**{ key: value }, **default_values}
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ści 10**5
i więcej. Ślad pamięciowy obu metod jest taki sam.
{**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 temu setdefault()
unikamy jednego dodatkowego wyszukiwania w słowniku, to znaczy, choć niewielkiego, ale wciąż zwiększającego wydajność.