所以我似乎无法弄清楚如何有效地实现这一点。我正在基于特定的键作为输入,将扁平化的字典嵌套到列表的字典中。如此拼命地学习
鉴于我的数据如下所示:
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
}
]
}
},
}
答案 0 :(得分:3)
您可以使用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}] }
}
}
[EDIT]概括该方法
如果您必须经常在不同类型的字典或层次结构上执行此类操作,则可以将其归纳为一个函数:
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