2013-09-02 11 views
12

Aby uzyskać dużą listę zagnieżdżonych słowników, chcę sprawdzić, czy zawierają one klucz. Każda z nich może lub nie może mieć jedną z zagnieżdżonych słowników, więc jeśli pętla I to wyszukiwanie przez wszystkie z nich zgłosi błąd:Sprawdź zagnieżdżone wartości słownika?

for Dict1 in DictionariesList: 
    if "Dict4" in Dict1['Dict2']['Dict3']: 
     print "Yes" 

Moje rozwiązanie tak daleko jest:

for Dict1 in DictionariesList:  
    if "Dict2" in Dict1: 
     if "Dict3" in Dict1['Dict2']: 
      if "Dict4" in Dict1['Dict2']['Dict3']: 
       print "Yes" 

Ale to ból głowy, brzydki i prawdopodobnie mało efektywny. Jaki byłby właściwy sposób na zrobienie tego w pierwszym typie, ale bez zgłaszania błędu, gdy słownik nie istnieje?

Odpowiedz

39

Zastosowanie .get() z pustymi słownikach jako domyślne:

if 'Dict4' in Dict1.get('Dict2', {}).get('Dict3', {}): 
    print "Yes" 

Jeśli klucz Dict2 nie jest obecny, pusta słownika wrócił, więc następnym przykuty .get() nie będzie również znaleźć Dict3 i powrócić pustego słownika z kolei . Test in następnie zwraca False.

Alternatywą jest po prostu złapać KeyError:

try: 
    if 'Dict4' in Dict1['Dict2']['Dict3']: 
     print "Yes" 
except KeyError: 
    print "Definitely no" 
+2

Niesamowite, przetestowane i działa, bardzo doceniane. Przyjmie jak najszybciej. Naprawdę Ninja. –

+1

Pierwsza propozycja zakończy się niepowodzeniem, jeśli w łańcuchu znajdą się klucze "Brak". Np. Test nie będzie działał dla 'Dict1 = {'Dict2': None}'. Wydaje się więc, że złapanie wyjątku jest najczystszym rozwiązaniem. –

+1

@AlexO: nie powiedzie się dla żadnego obiektu, który nie ma metody '.get()', tak. Zadaniem tego kodu nie jest uwzględnianie każdej możliwości; chyba że wyraźnie potrzebujesz obsługiwać różne typy wartości, nie przechwytuj tego wyjątku, ponieważ oznacza to błąd w innym miejscu. –

8

Jak o próbie/z wyjątkiem bloku:

for Dict1 in DictionariesList: 
    try: 
     if 'Dict4' in Dict1['Dict2']['Dict3']: 
      print 'Yes' 
    except KeyError: 
     continue # I just chose to continue. You can do anything here though