Jeśli naprawdę potrzebujesz zmodyfikować oryginalny słownik:
empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
del metadata[k]
Zauważ, że musimy zrobić listę pustych kluczy, ponieważ nie możemy modyfikować słownika podczas iteracji po nim (jak być może zauważyłeś). Jest to jednak mniej kosztowne (pod względem pamięci) niż tworzenie zupełnie nowego słownika, chyba że istnieje wiele wpisów z pustymi wartościami.
nneonneo
źródło
źródło
.iteritems()
go.items()
, pierwszy nie działa już w najnowszych wersjach Pythona.Odpowiedzi:
Rozwiązanie BrenBarna jest idealne (i dodam, że jest pytoniczne ). Oto jednak inne (fp) rozwiązanie:
źródło
Jeśli chcesz mieć w pełni funkcjonalne, ale zwięzłe podejście do obsługi rzeczywistych struktur danych, które są często zagnieżdżone, a nawet mogą zawierać cykle, polecam przyjrzenie się narzędziu do remapowania z pakietu narzędzi boltons .
Po
pip install boltons
skopiowaniu lub skopiowaniu iterutils.py do projektu po prostu wykonaj:Ta strona zawiera wiele innych przykładów, w tym te działające ze znacznie większymi obiektami z API Github.
Jest to czysty Python, więc działa wszędzie i jest w pełni przetestowany w Pythonie 2.7 i 3.3+. A co najlepsze, napisałem go dla dokładnie takich przypadków, więc jeśli znajdziesz przypadek, którego nie obsługuje, możesz mnie naprawić tutaj .
źródło
W oparciu o rozwiązanie Ryana , jeśli masz również listy i zagnieżdżone słowniki:
W przypadku Pythona 2:
W przypadku Pythona 3:
źródło
d = { "things": [{ "name": "" }] }
Jeśli masz zagnieżdżony słownik i chcesz, aby działał nawet dla pustych elementów podrzędnych, możesz użyć rekurencyjnego wariantu sugestii BrenBarna:
źródło
items()
zamiastiteritems()
dla Python 3Szybka odpowiedź (TL; DR)
Przykład01
Szczegółowa odpowiedź
Problem
Rozwiązanie
Pułapki
Alternatywny przykład
Przykład02
Zobacz też
źródło
W przypadku Pythona 3
źródło
Opierając się na odpowiedziach patriciasz i nneonneo i biorąc pod uwagę możliwość, że możesz chcieć usunąć klucze, które mają tylko pewne fałszywe rzeczy (np.
''
), Ale nie inne (np.0
), A może nawet chcesz uwzględnić pewne prawdziwe rzeczy (np.'SPAM'
) , wtedy możesz stworzyć bardzo szczegółową listę trafień:Niestety to nie do końca działa, ponieważ na przykład
0 in unwanted
wartościowane są doTrue
. Musimy rozróżniać0
i inne fałszywe rzeczy, więc musimy użyćis
:... ocenia się do
False
.Teraz użyj go do
del
niechcianych rzeczy:Jeśli chcesz mieć nowy słownik, zamiast modyfikować
metadata
w miejscu:źródło
[]
Przeczytałem wszystkie odpowiedzi w tym wątku, a niektóre odniosły się również do tego wątku: Usuń puste dykty w zagnieżdżonym słowniku z funkcją rekurencyjną
Pierwotnie zastosowałem tutaj rozwiązanie i działało świetnie:
Próba 1: Too Hot (niewydajne lub przyszłościowe) :
Jednak w świecie Pythona 2.7 pojawiły się pewne problemy z wydajnością i zgodnością:
isinstance
zamiasttype
for
pętlę w celu zwiększenia wydajnościitems
zamiastiteritems
Próba 2: Za zimno (brak zapamiętania) :
DOH! To nie jest rekurencyjne i wcale nie jest zapamiętywane.
Próba 3: w sam raz (jak dotąd) :
źródło
Dicts zmieszane z Arrays
if isinstance(v, list):
, który czyści listę przy użyciu oryginalnejscrub_dict(d)
implementacji.źródło
Alternatywnym sposobem, w jaki możesz to zrobić, jest użycie rozumienia ze słownika. Powinno to być zgodne z
2.7+
źródło
Oto opcja, jeśli używasz
pandas
:źródło
Niektóre z wyżej wymienionych metod ignorują obecność liczb całkowitych i zmiennoprzecinkowe z wartościami 0 i 0,0
Jeśli ktoś chce uniknąć powyższego, może użyć poniższego kodu (usuwa puste ciągi i wartości None z zagnieżdżonego słownika i listy zagnieżdżonej):
źródło
„Ponieważ obecnie piszę aplikację komputerową do pracy w języku Python, znalazłem w aplikacji do wprowadzania danych, w której jest dużo wpisów, a niektóre z nich nie są obowiązkowe, więc użytkownik może pozostawić ją pustą, w celu walidacji łatwo ją złapać wszystkie wpisy, a następnie odrzuć pusty klucz lub wartość słownika. Mój kod powyżej pokazuje, jak możemy je łatwo usunąć, używając rozumienia słownikowego i zachować element słownika, który nie jest pusty. Używam Pythona 3.8.3
źródło
Niektóre testy porównawcze:
1. Lista ze zrozumieniem odtworzyć dyktando
2. Lista ze zrozumieniem odtworzyć dict za pomocą dict ()
3. Klawisz zapętlania i usuwania, jeśli v ma wartość Brak
więc pętla i usuwanie są najszybsze przy 160 ns, rozumienie listy jest o połowę wolniejsze przy ~ 375 ns iz wywołaniem
dict()
jest znowu o połowę wolniejsze ~ 680 ns.Pakowanie 3 do funkcji sprowadza ją z powrotem do około 275ns. Również dla mnie PyPy był około dwa razy szybszy niż Neet Python.
źródło
list(dic.items())
do py 3. Więc powiedz ze zrozumieniem? del nadal wydaje się szybszy przy niskim stosunku wartości Null / puste. Wydaje mi się, że tworzenie tej listy jest równie szkodliwe dla zużycia pamięci niż tylko odtworzenie dyktatu.