簡體   English   中英

如何根據值刪除列表的嵌套字典中的鍵

[英]How to delete keys in a nested dictionary of lists based on the values

我正在處理一個表示類似於flare.json的樹狀結構的文件,該文件以D3.js社區而聞名。 在python中刪除樹上所有葉子的最佳方法是什么? 換句話說,我要刪除所有鍵中沒有“兒童”鍵的鍵。

例如:

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      {"name": "CommunityStructure", "size": 3812},
      {"name": "HierarchicalCluster", "size": 6714},
      {"name": "MergeEdge", "size": 743}
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "size": 3534},
      {"name": "LinkDistance", "size": 5731},
      {"name": "MaxFlowMinCut", "size": 7840},
      {"name": "ShortestPaths", "size": 5914},
      {"name": "SpanningTree", "size": 3416}
     ]
    },
    {
     "name": "optimization",
     "children": [
      {"name": "AspectRatioBanker", "size": 7074}
     ] ...

應該變成:

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
    },
    {
     "name": "graph",
    },
    {
     "name": "optimization",

     ] ...

換句話說,我只是在砍樹的葉子。 在子級列表為空時,應將其刪除。

我嘗試這樣做只是為了刪除密鑰,但是它不起作用:

def deleteLeaves(pTree):
    if pTree.has_key('children'):
        for child in pTree['children']:
            deleteLeaves(child)
    else:
        del pTree

這似乎與您想要的近似:

def pruneLeaves(obj):

  if isinstance(obj, dict):
    isLeaf = True
    for key in obj.keys():
      if key == 'children': isLeaf = False
      if pruneLeaves(obj[key]): del obj[key]
    return isLeaf

  elif isinstance(obj, list):
    leaves = []
    for (index, element) in enumerate(obj):
      if pruneLeaves(element): leaves.append(index)
    leaves.reverse()
    for index in leaves: obj.pop(index)
    return not bool(obj)

  else:  # String values look like attributes in your dict, so never prune them
    return False

使用截斷的數據樣本進行了測試:

data = {
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      {"name": "CommunityStructure", "size": 3812},
      {"name": "HierarchicalCluster", "size": 6714},
      {"name": "MergeEdge", "size": 743}
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "size": 3534},
      {"name": "LinkDistance", "size": 5731},
      {"name": "MaxFlowMinCut", "size": 7840},
      {"name": "ShortestPaths", "size": 5914},
      {"name": "SpanningTree", "size": 3416}
     ]
    }
   ]
  }
  ]
}

pruneLeaves(data)
print data

並得到以下結果:

{'name': 'flare', 'children': [{'name': 'analytics', 'children': [{'name': 'cluster'}, {'name': 'graph'}]}]}

我只是編輯了@rchang的答案 ,以解決刪除除children以外的列表的問題。

def pruneLeaves(self,obj):
    if isinstance(obj, dict):
        isLeaf = True
        for key in obj.keys():
            if key=='children': 
                isLeaf = False
                if self.pruneLeaves(obj[key]): del obj[key]
        return isLeaf

    elif isinstance(obj, list) :
        leaves = []
        for (index, element) in enumerate(obj):
          if self.pruneLeaves(element): leaves.append(index)
        leaves.reverse()
        for index in leaves: obj.pop(index)
        return not bool(obj)
    else:  # String values look like attributes in your dict, so never prune them
        return False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM