2017-01-09 6 views
9

辞書から取得しようとしている要素がある場合: my_dict[i]['level_1']['level_2']['my_var']Pythonの辞書要素のクリーンテストはありますか?

nullをチェックするよりもクリーンな方法がありますか?

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 

それとも、テストしたい場合は::

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 

あなたはin_deep(my_dict[i],'level1','level2','my_var')でこのコードを使用することができますし、それができるならば、それはTrueを返しますあなたは単にあなた自身を定義することができ

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

'dict.get' - ' my_dict [i] .get( 'level_1'、{})を使うことができます。get( 'level_2'、{ })。get( 'my_var') '。見つからなければ 'None'となります。 – jonrsharpe

+7

または 'try-except KeyError'ブロック –

+4

あなたのアプローチは、あなたが達成しようとしていることとあなたが望む動作に完全に依存します。 try-except'でラップされた簡単な 'my_var = my_dict [i] ['level_1'] ['level_2'] ['my_var']'は、あなたの性質に応じてjonsharpeが提案するもの、データ。 –

答えて

7

実際には辞書の中でそれを深く理解してください。深い要素を取得したい場合は、get_deep(my_dict[i],'level1','level2','my_var')と呼ぶことができます。 get_deepは、パスに到達できない場合に備えてdefaultパラメータ(デフォルトではNone)を返します。ここで

3

は私のワンライナーです:

# 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) 

例:削減の反復ごとに、それはpreviouisキーがターゲット辞書(x)にあったかどうかをチェックします。

どのように動作する
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 

。そうでない場合は、すぐにand条件のためにFalseを返し、リストの下にそれを伝播します。次に、要求されたキーがdict(x in y)にあるかどうかをチェックします。そうであれば、下位レベルの辞書をxとして下位レベルに渡します。

注:最後の要素(a ['b'] ['c'] ['d'])はTrueと評価する必要があります。 'd' in reduce(...)

関連する問題