122 votes

Rechercher toutes les occurrences d’une clé dans les dictionnaires et listes imbriqués

J’ai un dictionnaire comme celui-ci:

Fondamentalement, un dictionnaire avec des listes imbriquées, des dictionnaires et des chaînes, de profondeur arbitraire.

Quelle est la meilleure façon de parcourir cela pour extraire les valeurs de chaque clé « id »? Je veux obtenir l’équivalent d’une requête XPath comme « //id ». La valeur de « id » est toujours une chaîne.

Donc, de mon exemple, la sortie dont j’ai besoin est essentiellement:

L’ordre n’est pas important.

50voto

kev Points 41855
d = { "id" : "abcde",
    "key1" : "blah",
    "key2" : "blah blah",
    "nestedlist" : [ 
    { "id" : "qwerty",
        "nestednestedlist" : [ 
        { "id" : "xyz", "keyA" : "blah blah blah" },
        { "id" : "fghi", "keyZ" : "blah blah blah" }],
        "anothernestednestedlist" : [ 
        { "id" : "asdf", "keyQ" : "blah blah" },
        { "id" : "yuiop", "keyW" : "blah" }] } ] } 


def fun(d):
    if 'id' in d:
        yield d['id']
    for k in d:
        if isinstance(d[k], list):
            for i in d[k]:
                for j in fun(i):
                    yield j
 >>> list(fun(d))
['abcde', 'qwerty', 'xyz', 'fghi', 'asdf', 'yuiop']

43voto

arainchi Points 344
d = { "id" : "abcde",
    "key1" : "blah",
    "key2" : "blah blah",
    "nestedlist" : [
    { "id" : "qwerty",
        "nestednestedlist" : [
        { "id" : "xyz", "keyA" : "blah blah blah" },
        { "id" : "fghi", "keyZ" : "blah blah blah" }],
        "anothernestednestedlist" : [
        { "id" : "asdf", "keyQ" : "blah blah" },
        { "id" : "yuiop", "keyW" : "blah" }] } ] }


def findkeys(node, kv):
    if isinstance(node, list):
        for i in node:
            for x in findkeys(i, kv):
               yield x
    elif isinstance(node, dict):
        if kv in node:
            yield node[kv]
        for j in node.values():
            for x in findkeys(j, kv):
                yield x

print(list(findkeys(d, 'id')))

29voto

Alfe Points 12023
<pre><code></code><p>EDIT: @Anthon remarqué que cela ne fonctionnera pas pour les listes directement imbriquées. Si vous avez ceci dans votre entrée, vous pouvez utiliser ceci:</p><pre><code></code></pre><p>Mais je pense que la version originale est plus facile à comprendre, alors je vais la laisser.</p></pre>

6voto

Dolan Antenucci Points 3377

Une autre variante, qui inclut le chemin d’accès imbriqué aux résultats trouvés (remarque: cette version ne prend pas en compte les listes):

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X