走进字典以找到所需的键

时间:2019-07-09 09:15:35

标签: python dictionary

我能够递归地获取键为extras的特定节点中所有键的值:

def findkeys(node, kv):
    if isinstance(node, list):
        for i in node:
            for x in findkeys(i, kv):
                yield x
    elif isinstance(node, dict):
        if kv in node:
            yield node[kv]
        for j in node.values():
            for x in findkeys(j, kv):
                yield x 

使用以下输入:

a = {'product': {'extras': {'size': 'large', 'color': 'green', 'name':'shirt'}, 'cat': 'male', 'season': 'summer'}, 'id': 'a12b', 'brand': 'aua'}
print(list(findkeys(a, 'extras')))

输出是所需的:

  

[{''size':'大号','color':'绿色','name':'衬衫'}]

但是,如何将我的功能更改为另外捕获catid?请注意,我要捕获Extras的同级钥匙猫和Extras的父键ID。对我来说,最佳输出应该是:

  

[{''size':'large','color':'green','name':'shirt','cat':'male','id':'a12b'}]

还请注意,字典中可能没有product。这就是为什么我需要首先找到临时演员(始终存在)并搜索其兄弟姐妹和父母的原因

根据评论中的建议,请找到附带完整词典的附有可能的情况:

{  
   "contents":[  
      {  
         "product":{  
            "extras":{  
               "size":"large",
               "color":"green",
               "name":"shirt"
            },
            "cat":"male"
         },
         "id":"a12b"
      },
      {  
         "products":{  
            "extras":{  
               "size":"small",
               "color":"red",
               "name":"trouser"
            },
            "cat":"male",
            "price":12.21
         },
         "id":"a23b"
      },
      {  
         "produkt":{  
            "extras":{  
               "size":"medium",
               "color":"yellow",
               "name":"hat"
            },
            "cat":"female",
            "price":2.87,
            "units":100
         },
         "id":"a34b"
      }
   ]
}

请注意,由于产品可能不存在(可能会出现其他变化),所以我不能仅使用['product']在对象中导航。这种方式来自数据源。我想要的输出:

[{'size': 'large', 'color': 'green', 'name': 'shirt', 'cat': 'male', 'id': 'a12b' },
{'size': 'small', 'color': 'red', 'name': 'trouser', 'cat': 'male', 'id': 'a23b' },
{'size': 'medium', 'color': 'yellow','name': 'hat', 'cat': 'female', 'id': 'a34b' }]

2 个答案:

答案 0 :(得分:1)

未经全面测试,仅基于当前函数并添加了可变参数来存储值:

def findkeys(node, kv, data={}):
    if isinstance(node, list):
        for i in node:
            for x in findkeys(i, kv):
                yield x
    elif isinstance(node, dict):
        id = node.get("id")
        if id:
            data["id"] = id
        if kv in node:
            data["cat"] = node.get("cat")
            data.update(node[kv])
            yield data
            data.clear()
        for j in node.values():
            for x in findkeys(j, kv):
                yield x

for i in findkeys(b["contents"], 'extras'):
    print (i)

结果:

{'id': 'a12b', 'cat': 'male', 'size': 'large', 'color': 'green', 'name': 'shirt'}
{'id': 'a23b', 'cat': 'male', 'size': 'small', 'color': 'red', 'name': 'trouser'}
{'id': 'a34b', 'cat': 'female', 'size': 'medium', 'color': 'yellow', 'name': 'hat'}

答案 1 :(得分:0)

'cat'是您要查找的项目的同级,而'id'是“叔叔”。您的递归函数将需要自己传递它经历的子词典的“路径”,以便您可以回溯到找到的键的父级和祖父级。