2016-08-08 49 views
0

Ich habe einen JSON dict wie folgt aus:Iterate über verschachtelte Schlüssel in Python dict und brechen beim ersten Auftreten

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

ich den Wert des Schlüssels "b1" im Wörterbuch überprüfen möchten, und bekommen, wenn ich Finde b1=True. Wenn ich das gesamte dict (verschachtelte Schlüssel eingeschlossen) überprüfe und ich b1 = True nicht finde, möchte ich False zurückgeben. Für das obige Beispiel sollte meine Funktion True zurückgeben.

Grundsätzlich möchte ich den Code beim ersten Auftreten von b1=True brechen und iterieren über alle Schlüssel des dict (in allen Ebenen), und wenn dieses Vorkommen nicht existiert, geben Sie False zurück.

Dies ist, was ich kam mit:

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 

Mein Code immer wieder False.

Antwort

4

Sie müssen von der rekursiven Anrufe auch zurückkehren, und verwenden Sie das, um zu informieren, ob Sie Schleife fortsetzen werden; Ihr Code ignoriert, was der rekursive Aufruf isb1True(value) zurückgibt.

Sie können die any() function kurzzuschließen rekursive Werte verwenden Testen:

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

Die oben rekursiv für jeden Schlüssel, der nicht 'b1' ist, und Rekursion stoppt, wenn dieser Wert kein Wörterbuch ist (darin welchem ​​Fall wird nicht b1 sein, so dass das Ergebnis kein 'b1': True Fall ist).

Ich gehe davon aus, dass 'b1' immer auf einen booleschen Wert gesetzt ist; Das obige gibt True für jeden 'truthy' Wert für diesen Schlüssel zurück.

Einige Testfälle:

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

Vielen Dank! Dies löste mein Problem: D (ich musste es leicht ändern, weil ich doppelte Schlüssel habe und die Art, wie ich damit umgehe, ist, dass ich eine Liste von Werten für jeden duplizierten Schlüssel habe;)) – Samiella