2013-09-01 2 views
0

У меня есть dicionary, как это здесь:Создать Parent словаря по ключевым

example_dict = { 
    'key1' : 'value1', 
    'key2' : 'value2', 
    'key3' : 
    { 
     'key3a': 'value3a' 
    }, 
    'key4' : 
    { 
     'key4a': 
     { 
      'key4aa': 'value4aa', 
      'key4ab': 'value4ab', 
      'key4ac': 
      { 
       'key4ac1': [0,1,2], 
       'key4ac2': (3,4,5), 
       'key4ac3': [ 
        { 
         'sub_key_x': 0, 
         'sub_key_y': 1, 
        }, 
        6 
       ]    
      } 
     }, 
     'key4b': 'value4b' 
    } 
} 

Я пытался создать родительский словарь, используя рекурсивный код этого вопроса: Get parents keys from nested dictionary

задач являются кортежами или списки , которые разрушают цикл. Я хотел искать строки в словаре, сортируя наиболее подходящие результаты с помощью difflib.

Было бы очень приятно, если у кого-нибудь есть идея/схема, как искать в словаре для ключей/значений, создающих родительский словарь.

, например:

search_in_dict(example_dict, 'sub key') 
# returning the content of: 
# example_dict['key4']['key4a']['key4ac']['key4ac3'] 

вид касается баумкухен

ответ

0

Я не знаю, почему вы хотите это сделать, такого рода вещи будет медленным, когда размер увеличивается структуры данных. Вероятно, было бы лучше иметь плоский словарь, однако алгоритм выравнивания должен быть определен.

Я сделал что-то грубое для того, что, я думаю, вы хотите. Метод flatten возвращает что-то похожее на items (список кортежей (ключ, значение)), где «ключ» на самом деле является кортежем ключей. Это необходимо, поскольку словари могут содержать один и тот же ключ, поэтому при преобразовании в плоское пространство имен (которое требует уникальных ключей) возникает конфликт.

class recurdict(dict): 
    ''' 
    Recursive Dictionary 
    ''' 
    def __init__(self, idict=None, **kwargs): 
     dict.__init__(self) 
     if idict is not None: 
      self.update(idict) 
     if len(kwargs): 
      self.update(kwargs) 

    def __contains__(self, key): 
     return (key in self.keys()) 

    def __getitem__(self, key): 
     if self.__contains__(key): 
      return self.___getitem__(self, key) 
     else: 
      raise KeyError(key) 

    @staticmethod 
    def ___getitem__(idict, key): 
     if dict.__contains__(idict, key): 
      return dict.__getitem__(idict, key) 
     else: 
      result = None 
      for k, v in idict.iteritems(): 
       if hasattr(v, "keys"): 
        result = recurdict.___getitem__(v, key) 
        if(result): 
         return result 
        else: 
         continue 

    def flatten(self): 
     return self._flatten(self) 

    @staticmethod 
    def _flatten(idict, key_chain = []): 
     found_keys = [] 
     for k, v in idict.iteritems(): 
      if hasattr(v, "keys"): 
       found_keys.extend(recurdict._flatten(v, key_chain + [k])) 
      else: 
       found_keys.append((tuple(key_chain + [k]), v)) 
     return found_keys 

    def has_key(self, key): 
     return self.__contains__(key) 

    def keys(self): 
     return self._keys(self) 

    @staticmethod 
    def _keys(idict): 
     found_keys = dict.keys(idict) 
     for k, v in idict.iteritems(): 
      if hasattr(v, "keys"): 
       found_keys.extend(recurdict._keys(v)) 
     return found_keys 

    def update(self, other=None, **kwargs): 
     if other is None: 
      pass 
     elif hasattr(other, "iteritems"): 
      for k, v in other.iteritems(): 
       self.__setitem__(k,v) 
     elif hasattr(other, "keys"): 
      for k in other.keys(): 
       self.__setitem__(k,other.__getitem__(k)) 
     else: 
      for k, v in other: 
       self.__setitem__(k,v) 
     if kwargs: 
      self.update(kwargs) 

example_dict = recurdict\ 
({ 
    "key1" : "value1", 
    "key2" : "value2", 
    "key3" : 
    { 
     "key3a": "value3a" 
    }, 
    "key4" : 
    { 
     "key4a": 
     { 
      "key4aa": "value4aa", 
      "key4ab": "value4ab", 
      "key4ac": 
      { 
       "key4ac1": [0,1,2], 
       "key4ac2": (3,4,5), 
       "key4ac3": 
       [ 
        { 
         "sub_key_x": 0, 
         "sub_key_y": 1, 
        }, 
        6 
       ]    
      } 
     }, 
     "key4b": "value4b" 
    } 
}) 

print example_dict.keys() 
print "key1" in example_dict 
print "key4ac1" in example_dict 
print example_dict["key4ac1"] 
for (k, v) in example_dict.flatten(): 
    print (k, v) 
+0

спасибо, хорошо работает =) Для того, чтобы ответить на вопрос, почему я хочу это, что я пишу сценарий для маневра через словари (пользователь может выбрать ключ и получить содержание отображается, ..) , который работает до сих пор, но я также хотел реализовать функцию поиска, чтобы быстрее находить некоторые ключи/значения. – BaumKuchen

Смежные вопросы