Wiem, aby bezpiecznie usunąć wpis, „klucz” z mojego słownika d
, robisz to:
if d.has_key('key'):
del d['key']
Jednak muszę bezpiecznie usunąć wiele wpisów ze słownika. Myślałem o zdefiniowaniu wpisów w krotce, ponieważ będę musiał to zrobić więcej niż raz.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
Zastanawiałem się jednak, czy istnieje mądrzejszy sposób, aby to zrobić?
python
dictionary
dublintech
źródło
źródło
key in d
jest bardziej Pythonic niżd.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Będzie to prawdopodobnie bardziej wydajne tylko wtedy, gdyentities_to_remove
będzie „duże”.Odpowiedzi:
Dlaczego nie tak:
Bardziej zwarta wersja została dostarczona przez mattbornskiego za pomocą dict.pop ()
źródło
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
i obejściekey in dict
testu.źródło
dict.pop()
eliminuje potrzebę testowania obecności kluczy. Doskonały..pop()
jest to zła i niepytoniczna, i wolałabym zaakceptowaną odpowiedź od tej.setdefault
. Jeśli zaimplementowano poprawnie (i jestem pewien, że tak), wykonuje tylko jedno wyszukiwanie w mapie skrótów, czylidict
zamiast dwóch.Korzystanie ze zrozumiałych słów
gdzie klucz1 i klucz2 mają zostać usunięte.
W poniższym przykładzie klucze „b” i „c” mają zostać usunięte i są przechowywane na liście kluczy.
źródło
O(n)
. Cała operacja polega na tymO(mn)
, żem
jest to liczba kluczy w dyktandzie in
liczba kluczy na liście.{key1, key2}
Jeśli to możliwe, sugeruję użycie zestawu .rozwiązaniem jest użycie
map
ifilter
funkcjonujepython 2
python 3
dostajesz:
źródło
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... w funkcji mapy Python 3.4 zwraca iteratordeque(map(...), maxlen=0)
aby uniknąć tworzenia listy wartości Brak; pierwszy import zfrom collections import deque
Jeśli potrzebujesz również pobrać wartości usuwanych kluczy, byłby to całkiem dobry sposób:
Oczywiście możesz to zrobić tylko po to, aby usunąć klucze z
d
, ale niepotrzebnie utworzyłbyś listę wartości za pomocą funkcji list. Trochę niejasne jest również użycie funkcji rozumienia listy tylko dla efektu ubocznego funkcji.źródło
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
i tak dalej.Znalazłem rozwiązanie za pomocą
pop
imap
Wynik tego:
Odpowiedziałem na to pytanie tak późno, ponieważ myślę, że w przyszłości pomoże to, jeśli ktoś będzie szukał tego samego. I to może pomóc.
Aktualizacja
Powyższy kod spowoduje wyświetlenie błędu, jeśli klucz nie istnieje w dict.
wynik:
źródło
keys
nie istniejed
- najpierw musiałbyś go odfiltrować.Nie mam problemu z żadną z istniejących odpowiedzi, ale zdziwiłem się, że nie znalazłem tego rozwiązania:
Uwaga: natknąłem się na to pytanie, przychodząc stąd . A moja odpowiedź jest związana z tą odpowiedzią .
źródło
Dlaczego nie:
Nie wiem, co masz na myśli mówiąc „mądrzejszy sposób”. Z pewnością istnieją inne sposoby, być może ze słownikiem:
źródło
inline
źródło
Niektóre testy czasowe dla cpythona 3 pokazują, że prosta pętla for jest najszybszym sposobem i jest całkiem czytelna. Dodanie funkcji również nie powoduje dużego obciążenia:
wyniki timeit (10 tys. iteracji):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
W przypadku małych iteracji robienie tego „inline” było nieco szybsze z powodu narzutu wywołania funkcji. Ale
del_all
jest bezpieczny, wielokrotnego użytku i szybszy niż wszystkie konstrukcje rozumienia i mapowania Pythona.źródło
Myślę, że użycie faktu, że klucze można traktować jako zestaw, jest najmilszym sposobem, jeśli korzystasz z Pythona 3:
Przykład:
źródło
Byłoby miło mieć pełne wsparcie dla metod ustawiania dla słowników (a nie przeklętego bałaganu, który dostajemy w Pythonie 3.9), abyś mógł po prostu „usunąć” zestaw kluczy. Jeśli jednak tak nie jest i masz duży słownik z potencjalnie dużą liczbą kluczy do usunięcia, możesz chcieć wiedzieć o wydajności. Stworzyłem więc kod, który tworzy coś wystarczająco dużego do znaczących porównań: macierz 100 000 x 1000, czyli łącznie 10 000,00 elementów.
10 milionów lub więcej elementów nie jest niczym niezwykłym w niektórych sytuacjach. Porównując dwie metody na moim komputerze lokalnym, widzę niewielką poprawę podczas używania
map
ipop
prawdopodobnie z powodu mniejszej liczby wywołań funkcji, ale obie zajmują około 2,5 sekundy na moim komputerze. Ale to blednie w porównaniu z czasem potrzebnym do utworzenia słownika w pierwszej kolejności (55 s) lub z uwzględnieniem sprawdzeń w pętli. Jeśli jest to prawdopodobne, najlepiej jest utworzyć zestaw będący przecięciem kluczy słownika i filtru:keys = cells.keys() & keys
Podsumowując:
del
jest już mocno zoptymalizowany, więc nie martw się o jego używanie.źródło
Spóźniłem się na tę dyskusję, ale dla kogokolwiek innego. Rozwiązaniem może być utworzenie listy kluczy jako takiej.
Następnie użyj pop () w składaniu listowym lub pętli for, aby iterować po klawiszach i wyskakiwać pojedynczo.
Wartość „n / a” oznacza, że klucz nie istnieje, należy zwrócić wartość domyślną.
źródło
new_dictionary
wygląda strasznie jak lista;)