2017-01-09 38 views
9

Jeśli mam element, który próbuję uzyskać ze słownika: my_dict[i]['level_1']['level_2']['my_var'].Czy istnieje czysty test dla elementu słownika w Pythonie?

Czy jest lepszy sposób niż sprawdzanie zerowych wartości?

if 'level_1' in my_dict[i]: 
    if 'level_2' in my_dict[i]['level_1']: 
     if 'my_var' in my_dict[i]['level_1']['level_2']: 
      my_var = my_dict[i]['level_1']['level_2']['my_var'] 
+8

Możesz użyć 'dict.get' -' my_dict [i] .get ('level_1', {}). Get ('level_2', { }). get ('my_var') '. Będzie "Brak", jeśli nie zostanie znaleziony. – jonrsharpe

+7

lub blok 'try-except KeyError' –

+4

Twoje podejście będzie zależeć wyłącznie od tego, co próbujesz osiągnąć i od pożądanego zachowania. Proste 'my_var = my_dict [i] ['level_1'] ['level_2'] ['my_var']' owinięte w 'try-except 'może być sposobem, aby przejść, lub co zaproponował jonsharpe, w zależności od charakteru ciebie dane. –

Odpowiedz

7

można po prostu zdefiniować własne:

def get_deep(dic,*keys,default=None): 
    for key in keys: 
     if isinstance(dic,dict) and key in dic: 
      dic = dic[key] 
     else: 
      return default 
    return dic 

Lub jeśli chcesz przetestować:

def in_deep(dic,*keys): 
    for key in keys: 
     if isinstance(dic,dict) and key in dic: 
      dic = dic[key] 
     else: 
      return False 
    return True 

Można użyć tego kodu z in_deep(my_dict[i],'level1','level2','my_var') i powróci True jeśli to możliwe rzeczywiście to głęboko w słowniku. Jeśli chcesz uzyskać głęboki element, możesz zadzwonić pod numer get_deep(my_dict[i],'level1','level2','my_var'). get_deep zwróci parametr default (domyślnie None) w przypadku, gdy nie może osiągnąć ścieżki.

3

Oto mój jeden-liner:

# returns False or the value of the end element 
reduce(lambda x, y: x and y in x and x[y], list_of_keys, target_dictionary) 

Przykład:

a = {'b': {'c': {'d': True}}} 
reduce(lambda x, y: x and y in x and x[y], ['b', 'c', 'd'], a) # True 
reduce(lambda x, y: x and y in x and x[y], ['b', 'cd', 'd'], a) # False 

Jak to działa: w każdej iteracji zmniejszyć, sprawdza czy previouis klucze były w słowniku docelowej (x) . Jeśli nie, zwróci False z powodu warunku and natychmiast i rozpropaguje go na liście. Następnie sprawdzi, czy żądany klucz znajduje się w dykcie (x in y). Jeśli tak, przejdzie przez słownik niższego poziomu na niższy poziom jako x.

Uwaga: ostatni element (a ['b'] ['c'] ['d']) musi mieć wartość True. Jeśli spodziewasz się fałszywej na końcu, sprawdź ostatni poziom jawnie: 'd' in reduce(...)