Je suis nouveau sur Python et j'ai essayé de chercher, mais je peux sembler trouver un échantillon de ce que j'essaie d'accomplir. Toutes les idées sont très appréciées. Je travaille avec un dictionnaire imbriqué avec beaucoup de clés et de valeurs, mais je souhaite uniquement imprimer celles spécifiques à l'aide d'une variable de liste filtrée.
my_nested_dict = {"global": {"peers": {"15.1.1.1": {"remote_id": "15.1.1.1", "address_family": {"ipv4": {"sent_prefixes": 1, "received_prefixes": 4, "accepted_prefixes": 4}}, "remote_as": 65002, "uptime": 13002, "is_enabled": true, "is_up": true, "description": "== R3 BGP Neighbor ==", "local_as": 65002}}, "router_id": "15.1.1.2"}}
Je voudrais filtrer et choisir les clés et les valeurs à imprimer
filtered_list = ['peers', 'remote_id', 'remote_as', 'uptime']
et réaliser un sur
peers: 15.1.1.1
remote_id: 15.1.1.1
remote_as: 65002
uptime: 13002
Utilisez récursivité et isinstance
:
my_nested_dict = {"global": {"peers": {"15.1.1.1": {"remote_id": "15.1.1.1", "address_family": {"ipv4": {"sent_prefixes": 1, "received_prefixes": 4, "accepted_prefixes": 4}}, "remote_as": 65002, "uptime": 13002, "is_enabled": True, "is_up": True, "description": "== R3 BGP Neighbor ==", "local_as": 65002}}, "router_id": "15.1.1.2"}}
filtered_list = ['peers', 'remote_id', 'remote_as', 'uptime']
def seek_keys(d, key_list):
for k, v in d.items():
if k in key_list:
if isinstance(v, dict):
print(k + ": " + list(v.keys())[0])
else:
print(k + ": " + str(v))
if isinstance(v, dict):
seek_keys(v, key_list)
seek_keys(my_nested_dict, filtered_list)
Remarque: Il y a une hypothèse intrinsèque ici que si vous voulez un jour la "valeur" d'une clé dont la valeur est un autre dictionnaire, vous obtenez la clé en premier .
En plus de la réponse de @JacobIRR; je dirais que vous pouvez essayer de mettre en cache les données récurrentes dans un dict plat. De cette façon, ce sera beaucoup plus rapide que de récidiver à chaque fois. Ne vous inquiétez pas pour la mémoire car les valeurs du dict plat ne feront que se référer aux objets originaux du dictionnaire profond. Je vous laisse la modification du code de JacobIRR :).
@JacobIRR a posté une excellente réponse, mais puisque vous essayez de joindre les clés correspondantes à la valeur correspondante, une solution beaucoup plus courte apparaît:
my_nested_dict = {"global": {"peers": {"15.1.1.1": {"remote_id": "15.1.1.1", "address_family": {"ipv4": {"sent_prefixes": 1, "received_prefixes": 4, "accepted_prefixes": 4}}, "remote_as": 65002, "uptime": 13002, "is_enabled": True, "is_up": True, "description": "== R3 BGP Neighbor ==", "local_as": 65002}}, "router_id": "15.1.1.2"}}
_list = ['peers', 'remote_id', 'remote_as', 'uptime']
def _join(a, b):
return '{}:{}\n'.format(a, _keys(b, True) if isinstance(b, dict) else b)
def _keys(_d, flag = False):
return ''.join(_join(a, b) if a in _list else (a+'\n' if flag else '')+_keys(b)
for a, b in _d.items())
print(get_keys(my_nested_dict))
Sortie:
peers:15.1.1.1
remote_id:15.1.1.1
remote_as:65002
uptime:13002
En Python 3, il est plus efficace et plus simple d’utiliser des générateurs au lieu de la récursivité:
from typing import Any, Tuple, Generator, FrozenSet
def search_in_dict(d: Any, keys: FrozenSet[str]) -> Generator[Tuple[str, Any], None, None]:
"""
Generate pairs key-value for found keys
"""
if not isinstance(d, dict):
return
for key, value in d.items():
if key in keys:
if isinstance(value, dict):
# Special case: return the first key from nested dict as value
yield key, Tuple(value.keys())[0]
else:
yield key, value
# continue to search deeper
yield from search_in_dict(value, keys)
puis pliez-le pour dicter à nouveau:
flatten_dict_with_results = dict(kv for kv in search_in_dict(my_nested_dict, keys=frozenset(filtered_list)))
Vous pouvez utiliser jsonparse_ng (pip install jsonparse-ng). Sans la valeur if/else, la clé "pairs" est imprimée telle quelle (un dict).
from jsonpath_ng.ext import parse
my_nested_dict = {
"global": {
"peers": {
"15.1.1.1": {
"address_family": {
"ipv4": {
"accepted_prefixes": 4,
"received_prefixes": 4,
"sent_prefixes": 1
}
},
"description": "== R3 BGP Neighbor ==",
"is_enabled": true,
"is_up": true,
"local_as": 65002,
"remote_as": 65002,
"remote_id": "15.1.1.1",
"uptime": 13002
}
},
"router_id": "15.1.1.2"
}
}
filtered_list = ['peers', 'remote_id', 'remote_as', 'uptime']
for list_item in filtered_list:
found = parse(f'$..{list_item}').find(my_nested_dict)
if found:
if list_item == 'peers':
print(f'{list_item} - {"".join(found[0].value.keys())}')
else:
print(f'{list_item} - {found[0].value}')