簡體   English   中英

將字典扁平化為列表字典的嵌套字典

[英]flattened dictionary into nested dictionary of dictionaries of lists

所以我似乎無法弄清楚如何有效地實現這一點。 我希望基於特定的鍵作為輸入,將一個扁平的字典嵌套到列表字典的字典中。 拼命地學習

鑒於我的數據如下所示:

data= [
  {
    "player": "Kevin Durant",
    "team": "Thunder",
    "location": "Oklahoma City",
    "points": 15

  },
  {
    "player": "Jeremy Lin",
    "team": "Lakers",
    "location": "Los Angeles",
    "points": 22
  },
  {
    "player": "Kobe Bryant",
    "team": "Lakers",
    "location": "Los Angeles",
    "points": 51
  },
  {
    "player": "Blake Griffin",
    "team": "Clippers",
    "location": "Los Angeles",
    "points": 26
  }
]

如果我給它像 reorder(data,['location','team','player']) 這樣的參數作為例子,我想返回這樣的東西

result={
  "Los Angeles": {
    "Clippers": {
      "Blake Griffin": [
        {
          "points": 26
        }
      ]
    },
    "Lakers": {
      "Kobe Bryant": [
        {
          "points": 51
        }
      ],
      "Jeremy Lin": [
        {
          "points": 22
        }
      ]
    }
  },
  "Oklahoma City": {
    "Thunder": {
      "Kevin Durant": [
        {
          "points": 15
        }
      ]
    }
  }, 
}

您可以使用 setdefault 函數在瀏覽數據時自動構建嵌套級別:

data= [
  {
    "player": "Kevin Durant",
    "team": "Thunder",
    "location": "Oklahoma City",
    "points": 15

  },
  {
    "player": "Jeremy Lin",
    "team": "Lakers",
    "location": "Los Angeles",
    "points": 22
  },
  {
    "player": "Kobe Bryant",
    "team": "Lakers",
    "location": "Los Angeles",
    "points": 51
  },
  {
    "player": "Blake Griffin",
    "team": "Clippers",
    "location": "Los Angeles",
    "points": 26
  }
]

nested = dict()
for d in data:
    nested.setdefault(d["location"],dict()) \
          .setdefault(d["team"],    dict()) \
          .setdefault(d["player"],  list()) \
          .append({"points":d["points"]})

輸出:

print(nested)

{  'Oklahoma City': 
    {  
       'Thunder': 
           {  'Kevin Durant': [{'points': 15}] }
    }, 
    'Los Angeles': 
    { 
       'Lakers': 
           {  
              'Jeremy Lin': [{'points': 22}], 
              'Kobe Bryant': [{'points': 51}]
           }, 
       'Clippers': 
           {  'Blake Griffin': [{'points': 26}] }
     }
  }

[編輯]概括該方法

如果您必須經常在不同類型的字典或層次結構上執行此類操作,則可以將其概括為一個函數:

def dictNesting(data,*levels):
    result = dict()
    for d in data:
        r = result
        for level in levels[:-1]:
            r = r.setdefault(d[level],dict())
        r = r.setdefault(d[levels[-1]],list())
        r.append({k:v for k,v in d.items() if k not in levels})
    return result

然后,您可以為該函數提供一個字典列表,后跟要嵌套的鍵的名稱:

byLocation = dictNesting(data,"location","team")

{  'Oklahoma City':
       {  'Thunder': [
              {'player': 'Kevin Durant', 'points': 15}]
       },
   'Los Angeles':
       {'Lakers': [
              {'player': 'Jeremy Lin', 'points': 22},
              {'player': 'Kobe Bryant', 'points': 51}],
        'Clippers': [
              {'player': 'Blake Griffin', 'points': 26}]
       }
}

如果要以不同的方式對相同的數據進行分組,只需更改字段名稱的順序:

byPlayer = dictNesting(data,"player","location","team")


{  'Kevin Durant':
       {  'Oklahoma City':
              {  'Thunder': [{'points': 15}] }
       },
   'Jeremy Lin':
       {  'Los Angeles':
              {'Lakers': [{'points': 22}]}
       },
   'Kobe Bryant':
       {  'Los Angeles':
              {'Lakers': [{'points': 51}]}
       },
   'Blake Griffin':
       {  'Los Angeles':
              {'Clippers': [{'points': 26}]}
       }
}

從那里您可以使用該函數並對其進行改進以在最低嵌套級別聚合數據:

def dictNesting(data,*levels,aggregate=False):
    result = dict()
    for d in data:
        r = result
        for level in levels[:-1]:
            r = r.setdefault(d[level],dict())
        r = r.setdefault(d[levels[-1]],[list,dict][aggregate]())
        content = ( (k,v) for k,v in d.items() if k not in levels)
        if aggregate:
            for k,v in content: r.setdefault(k,list()).append(v)
        else:
            r.append(dict(content))
    return result

輸出:

byCity = dictNesting(data,"location","team",aggregate=True)

{  'Oklahoma City':
        {'Thunder':
             {'player': ['Kevin Durant'], 'points': [15]}},
   'Los Angeles':
        {'Lakers':
             {'player': ['Jeremy Lin', 'Kobe Bryant'], 'points': [22, 51]},
         'Clippers':
             {'player': ['Blake Griffin'], 'points': [26]}
        }
}

lakersPlayers = byCity["Los Angeles"]["Lakers"]["player"] 
# ['Jeremy Lin', 'Kobe Bryant']

lakersPoints  = sum(byCity["Los Angeles"]["Lakers"]["points"]) 
# 73

暫無
暫無

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

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