首页 > 解决方案 > Python3 search by value in nested dictionaries and lists then get other nearest keys/values pair

问题描述

I have a dictionary like this:

{'targets': [{'hosts': ['google.fr'],
              'tags': {'country': 'fr',
                       'server': 'french'}},
             {'hosts': ['amazon.es'],
              'tags': {'country': 'es',
                       'server': 'spain'}},
             {'hosts': ['facebook.de'],
              'tags': {'country': 'de',
                       'server': 'germany'}},
             {'hosts': ['server1.fr', 'server2.fr', 'server3.fr'],
              'tags': {'country': 'fr',
                       'server': 'french'}}]}

Basically a dictionary with nested lists, dictionaries, and strings, of arbitrary depth.

What is the best way of traversing this to extract the nearest key 'tags' where 'host' equal to my search ?

My attempt:

#host = 'google.fr' or 'amazon.es' or 'facebook.de' or 'server1.fr' or 'server2.fr' or 'server3.fr'

for [idx, val] in enumerate(targets['targets']):
    h = targets['targets'][idx]['hosts']
    for i in h:
        if i == host and 'tags' in targets['targets'][idx]: # if equal to host and 'tags' key exist
            t = targets['targets'][idx]['tags']

            tags = ','.join("{!s}={!r}".format(key,val) for (key,val) in t.items())
            tags = tags.replace("'", "")

            pprint ("host: '{}'".format(host))
            pprint("tags: '{}'".format(tags))

Result:

"host: 'google.fr'"
"tags: 'country=fr,server=french'"
"host: 'amazon.es'"
"tags: 'country=es,server=spain'"
"host: 'facebook.de'"
"host: 'server1.fr'"
"tags: 'country=fr,server=french'"
"host: 'server2.fr'"
"tags: 'country=fr,server=french'"
"host: 'server3.fr'"
"tags: 'country=fr,server=french'"

I'm not a python expert and I'm sure it's possible to have better performance.

Benchmark:

        wwii        azro

real    0m0,087s    0m0,057s
user    0m0,071s    0m0,027s
sys     0m0,015s    0m0,028s

real    0m0,078s    0m0,067s
user    0m0,068s    0m0,056s
sys     0m0,009s    0m0,010s

real    0m0,074s    0m0,058s
user    0m0,062s    0m0,024s
sys     0m0,011s    0m0,034s

Looks like azro's performing better :)

标签: pythonpython-3.xlistdictionaryrecursion

解决方案


您可以删除索引迭代并查找主机包含而不是相等

host = "google.fr"
for target in targets['targets']:
    if host in target['hosts'] and 'tags' in target:
        tags = ','.join("{!s}={!r}".format(key, val) for (key, val) in target['tags'].items())
        tags = tags.replace("'", "")
        print("host: '{}'".format(host))
        print("tags: '{}'".format(tags))

推荐阅读