在python中获取嵌套字典的值

时间:2019-05-07 20:06:09

标签: python dictionary

我有一个嵌套的字典,如下所示。

myTodo= {          
                'taskid': '10',
                'taskstatus': 'in progress',

                'Kitchen': 
                {                    
                    'Stove':{
                                'LED1':
                                {
                                'taskid': '11',
                                'taskstatus':'running'
                                },

                                'LED2':
                                {
                                    'taskid': '12',
                                    'taskstatus':'off',
                                    'LEDSub':
                                    { 
                                       'taskid': '13',
                                       'taskstatus':'stable',
                                       'LEDSub2':
                                        {
                                           'taskid': '14',
                                           'taskstatus':'burnt'
                                        }
                                    }
                                },

                                'LED3':
                                {
                                'taskid': '15',
                                'taskstatus':'new'
                                } 
                           },
                  //other nested layers
               }

我有一个python方法,该方法根据键向我返回到达“值”的路由。 该方法如下所示。

 def route(myTodo, id):
        q = list()
        q.append((list(), myTodo))
        while q:
            this_key_chain, this_v = reverse_linked_q.pop()
            # finish search if found the id 
            if this_v == id:
                return this_key_chain
            # not found. keep searching        
            try:
                items = this_v.items()
            except AttributeError:
                continue
            for k, v in items:
                q.append((this_key_chain + [k], v))
        raise KeyError

此方法根据键返回路线。因此,如果我route(myTodo, "11"),它将返回列表keyroute = [“ Kitchen”,“ Stove”,“ LED1”,“ taskid”]。

然后我从关键路由列表中删除“ taskid”,并将该列表发送到以下方法。

    def createOutputDic(keyroute, myTodo):
        for k in keyroute:
            myTodo = myTodo.get(k)
        return j

对于route(myTodo, "11")createOutputDic(keyroute,myTodo)的输出为

{ 
 'taskid': '11',
 'taskstatus':'running'
}

route(myTodo, "12")拨打电话时出现问题。我希望得到

{ 'taskid': '12',
  'taskstatus':'off'
}

但结果是

{ 
  'taskid': '12',
  'taskstatus':'off',
  'LEDSub':
   { 
     'taskid': '13',
     'taskstatus':'stable',
   'LEDSub2':
   {
     'taskid': '14',
     'taskstatus':'burnt'
   }
}

我只想得到

{ 'taskid': '12',
  'taskstatus':'off'
}

但是我不明白为什么当前的route(..)方法无法做到这一点。 字典可能嵌套得很深,我想有一个通用的方法。 有人可以帮助我,或指导我以更好的方式解决此问题吗?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

您可以对generator使用递归:

def get_data(d, val):
  if any(c == val for c in d.values()):
     yield {i:d.get(i) for i in ['taskid', 'taskstatus']}
  else:
     for i in d.values():
        if isinstance(i, dict):
           yield from get_data(i, val)

myTodo = {'taskid': '10', 'taskstatus': 'in progress', 'Kitchen': {'Stove': {'LED1': {'taskid': '11', 'taskstatus': 'running'}, 'LED2': {'taskid': '12', 'taskstatus': 'off', 'LEDSub': {'taskid': '13', 'taskstatus': 'stable', 'LEDSub2': {'taskid': '14', 'taskstatus': 'burnt'}}}, 'LED3': {'taskid': '15', 'taskstatus': 'new'}}}}
result = list(get_data(myTodo, '12'))
print(result if not result else result[0])

输出:

{'taskid': '12', 'taskstatus': 'off'}

要格式化输出,将使用所需输出中包含的相同键创建字典。 yield语句创建一个生成器对象,该生成器对象指向内存中其他对象,这些对象在运行中“已生成”。基于生成器的解决方案比使用return更加干净,因为后者需要在第二个for循环之外创建一个列表,每个get_data调用返回的结果都可以使用该列表附加到。最终,在每次yield调用中仅使用get_data会更清洁。