2010-03-26 3 views

Répondre

5

@ solution récursive de Håvard va probablement être OK ... à moins que le niveau d'imbrication est trop élevé, et vous obtenez un RuntimeError: maximum recursion depth exceeded. Pour remédier à cela, vous pouvez utiliser la technique habituelle de suppression de récursivité: conservez votre propre pile d'éléments à examiner (sous forme de liste sous votre contrôle). À savoir:

def find_key_nonrecursive(adict, key): 
    stack = [adict] 
    while stack: 
    d = stack.pop() 
    if key in d: 
     return d[key] 
    for k, v in d.iteritems(): 
     if isinstance(v, dict): 
     stack.append(v) 

La logique ici est assez proche de la réponse récursive (sauf pour la vérification des dict de la bonne façon ;-), à l'exception évidente que les appels récursifs sont remplacés par une boucle while et .pop et .append opérations sur la liste de la pile explicite, stack.

+0

Savez-vous exactement quelle est la profondeur de récursivité maximale? D'après ce que je comprends, il devrait être imbriqué au moins 100 mètres de profondeur, mais je ne suis pas complètement sûr. –

+0

@Goose Bumper: 'import sys; sys.getrecursionlimit() '. En outre, 'sys.setrecursionlimit()' – gorsky

+0

@ gorsky: merci! Pour tout le monde, la limite de récursivité sur mon ordinateur est de 1000. –

2

(Faire des vagues suppositions au sujet de votre structure de données ...)

Faites-récursive:

def findkey(d, key): 
    if key in d: return d[key] 
    for k,subdict in d.iteritems(): 
     val = findkey(subdict, key) 
     if val: return val 
+2

Si une valeur qui n'est pas elle-même un dict est toujours rencontrée dans la récursion, cette approche va essayer de l'indexer, ou d'appeler iteritems sur ce non-dire, et donc échouer tout à fait. –

0

traverse juste le dictionnaire et vérifiez les clés (notez le commentaire dans le fond de la valeur "non trouvé").

def find_key_recursive(d, key): 
    if key in d: 
    return d[key] 
    for k, v in d.iteritems(): 
    if type(v) is dict: # Only recurse if we hit a dict value 
     value = find_key_recursive(v, key) 
     if value: 
     return value 
    # You may want to return something else than the implicit None here (and change the tests above) if None is an expected value 
+0

ce n'est pas la façon de vérifier le type d'objet. @jathanism: et quelles sont les autres manières possibles d'utiliser la fonction récursive? – SilentGhost

+0

@SilentGhost mis à jour pour utiliser le plus approprié est la vérification. –

+1

Hmmm ... au lieu de 'type (v)' est 'dict', ne devriez-vous pas utiliser' instanceof (v, dict) '? Le premier n'accepte pas les sous-classes de 'dict'. En outre, si vous vérifiez l'existence de '__contains__' à la place, votre code acceptera également les autres objets qui supportent l'opérateur" in ", pas seulement les dicts. –

Questions connexes