Python: поиск ключа в многомерном словаре - PullRequest
3 голосов
/ 22 февраля 2011

Я использую библиотеку Python JSON с Google Maps API.Я пытаюсь получить почтовый индекс адреса, но иногда он находится в другом ключе словаря.Вот два примера (я обрезал JSON до того, что имеет отношение к делу):

placemark1 = {
  "AddressDetails": {
    "Country": {
      "AdministrativeArea": {
        "SubAdministrativeArea": {
          "Locality": {
            "PostalCode": {
              "PostalCodeNumber": "94043"
            }
          }
        }
      }
    }
  }
}

( Просмотреть полный JSON )

placemark2 = {
  "AddressDetails": {
    "Country" : {
      "AdministrativeArea" : {
        "Locality" : {
          "PostalCode" : {
            "PostalCodeNumber" : "11201"
          }
        }
      }
    }
  }
}

(Посмотреть полный JSON )

Итак, почтовые индексы:

zipcode1 = placemark1['AddressDetails']['Country']['AdministrativeArea']['SubAdministrativeArea']['Locality']['PostalCode']['PostalCodeNumber']
zipcode2 = placemark2['AddressDetails']['Country']['AdministrativeArea']['Locality']['PostalCode']['PostalCodeNumber']

Теперь я подумал, что, возможно, мне следует просто найти в многомерном словаре ключ "PostalCodeNumber".У кого-нибудь есть идеи, как этого добиться?Я хочу, чтобы это выглядело примерно так:

>>> just_being_a_dict = {}
>>> just_a_list = []
>>> counter_dict = {'Name': 'I like messing things up'}
>>> get_key('PostalCodeNumber', placemark1)
"94043"
>>> get_key('PostalCodeNumber', placemark2)
"11201"
>>> for x in (just_being_a_dict, just_a_list, counter_dict):
...     get_key('PostalCodeNumber', x) is None
True
True
True

Ответы [ 2 ]

2 голосов
/ 22 февраля 2011
def get_key(key,dct):
    if key in dct:
        return dct[key]
    for k in dct:
        try:
            return get_key(key,dct[k])
        except (TypeError,ValueError):
            pass
    else:
        raise ValueError

placemark1 = {
  "AddressDetails": {
    "Country": {
      "AdministrativeArea": {
        "SubAdministrativeArea": {
          "Locality": {
            "PostalCode": {
              "PostalCodeNumber": "94043"
            }
          }
        }
      }
    }
  }
}

placemark2 = {
  "AddressDetails": {
    "Country" : {
      "AdministrativeArea" : {
        "Locality" : {
          "PostalCode" : {
            "PostalCodeNumber" : "11201"
          }
        }
      }
    }
  }
}

just_being_a_dict = {}
just_a_list = []
counter_dict = {'Name': 'I like messing things up'}

for x in (placemark1, placemark2, just_being_a_dict, just_a_list, counter_dict):
    try:
        print(get_key('PostalCodeNumber', x))
    except ValueError:
        print(None)

урожайность

94043
11201
None
None
None
1 голос
/ 22 февраля 2011
from collections import Mapping

zipcode1 = {'placemark1':{'AddressDetails':{'Country':{'AdministrativeArea':{'SubAdministrativeArea':{'Locality':{'PostalCode':{'PostalCodeNumber':"94043"}}}}}}}}
zipcode2 = {'placemark2':{'AddressDetails':{'Country':{'AdministrativeArea':{'Locality':{'PostalCode':{'PostalCodeNumber':'11201'}}}}}}}

def treeGet(d, name):
    if isinstance(d, Mapping):
        if name in d:
            yield d[name]
        for it in d.values():
            for found in treeGet(it, name):
                yield found

возвращает все совпадающие значения в дереве:

>>> list(treeGet(zipcode1, 'PostalCodeNumber'))
['94043']
>>> list(treeGet(zipcode2, 'PostalCodeNumber'))
['11201']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...