2016-08-08 2 views
0

を破る、私は次のようなJSONの辞書を持っている:Pythonの辞書では、ネストされたキーを反復し、最初の出現に

   "{ 
         "a":1, 
         "b":{ 
          "b1":False, 
          "b2":{"b21": 2, "b22":8} 
         }, 
         "c": { 
          "b1":True, 
          "b2":2, 
          "b4":8 
         }, 
         "d":{ 
          "b1":False, 
          "d1":89 
         } 
         }" 

私は辞書で、キー"b1"の値をチェックし、ときに私出たいですb1=Trueを見つけてください。 dict(入れ子になったキーを含む)全体をチェックしても、b1 = Trueが見つからない場合は、Falseを返すようにします。上の例では、my関数はTrueを返します。

基本的には、b1=Trueの最初のオカレンスでコードを分割し、(すべてのレベルで)dictのすべてのキーに対して反復処理を行い、このオカレンスが存在しない場合はFalseを返します。

これは私が思いついたものです:

def isb1True(jsonDoc): 
    found = False 
    for (key,value) in jsonDoc.iteritems(): 
     if key=='b1': 
      if value==True : 
       found=True 
       break 
     else: 
      isb1True(value) 
    return found 

私のコードは常にFalseを返します。

答えて

4

再帰的なコールからリターンする必要があります。これを使用して、ループを継続するかどうかを通知します。あなたのコードは、再帰呼び出しisb1True(value)が返すものを無視します。

あなたが短絡テスト再帰値にany() functionを使用することができます。'b1'ない任意のキーの

def isb1true(d): 
    if not isinstance(d, dict): return False 
    return any(v if k == 'b1' else isb1true(v) for k, v in d.iteritems()) 

上記再帰、その値は辞書でない場合、再帰が停止し(この場合それをb1ではないので、結果は'b1': Trueではありません)。

私は'b1'が常にブール値に設定されていると仮定しています。上記の値は、そのキーの 'truthy'値に対してTrueを返します。

いくつかのテストケース:

>>> isb1true({'b1': True}) 
True 
>>> isb1true({'b1': False}) 
False 
>>> isb1true({'b': {'b1': True}}) 
True 
>>> isb1true({'b': {'b1': False}}) 
False 
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz', 'b1': True}}}) 
True 
>>> isb1true({'b': {'c': True, 'spam': 'eggs', 'ham': {'bar': 'baz'}}}) 
False 
+0

ありがとうございました!これは私の問題を解決しました:D(キーが重複しているために少し修正しなければならず、扱う方法はそれぞれの重複したキーの値のリストを持っています) – Samiella

関連する問題