Python 解析和创建嵌套字典

Python 解析和创建嵌套字典,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我想创建一个包含嵌套字典结构的字典,如下所示: { "Jaque": { "ES": { "Madrid": [ { "experience": 9 } ] }, "FR": { "Lyon": [ { "experience": 11.4 } ], "Paris": [ {

我想创建一个包含嵌套字典结构的字典,如下所示:


{
  "Jaque": {
    "ES": {
      "Madrid": [
        {
          "experience": 9
        }
      ]
    },
    "FR": {
      "Lyon": [
        {
          "experience": 11.4
        }
      ],
      "Paris": [
        {
          "experience": 20
        }
      ]
    }
  },
  "James": {
    "UK": {
      "London": [
        {
          "experience": 10.9
        }
      ]
    }
  },
  "Henry": {
    "UK": {
      "London": [
        {
          "experience": 15
        }
      ]
    }
  },
  "Joe": {
    "US": {
      "Boston": [
        {
          "experience": 100
        }
      ]
    }
  }
}
}
我的输入是以下格式的词典列表:

c = [{
    "country": "US",
    "city": "Boston",
    "name": "Joe",
    "experience": 100
  },
  {
    "country": "FR",
    "city": "Paris",
    "name": "Jaque",
    "experience": 20
  },
  {
    "country": "FR",
    "city": "Lyon",
    "name": "Jaque",
    "experience": 11.4
  },
  {
    "country": "ES",
    "city": "Madrid",
    "name": "Jaque",
    "experience": 9
  },
  {
    "country": "UK",
    "city": "London",
    "name": "Henry",
    "experience": 15
  },
  {
    "country": "UK",
    "city": "London",
    "name": "James",
    "experience": 10.9
  }
]
我的第一种方法是一步一步地创建嵌套dict:


dd=dict.fromkeys([i.get(“name”)表示c中的i],defaultdict(dict))
#将创造
#dd={'Joe':defaultdict(,{}),'Jaque':defaultdict(,{}),'James':defaultdict(,{}),'Henry':defaultdict(,{})}
对于dd中的i:
对于c中的j:
#验证d中的名称是否在dict j中
如果i在j.values()中:
dd[i]=dict(zip([a.get(“country”)表示a在c中,如果i在a.values()],[b.get(“city”)表示b在c中,如果i在b.values()]))
#dd将成为
#{'Joe':{'US':'Boston'},'Jaque':{'FR':'Lyon','ES':'Madrid'},'Henry':{'UK':'London'},'James':{'UK':'London'}

现在我想不出一种方法来创建/更新dict dd的嵌套结构。有没有更动态的方法来创建dict?Thx

您可以使用
itertools.groupby
以类似于预期输出的方式组织列表,然后循环转换为dict

from itertools import groupby
from operator import itemgetter

data = [{"country": "US", "city": "Boston", "name": "Joe", "experience": 100 }, {"country": "FR", "city": "Paris", "name": "Jaque", "experience": 20 }, {"country": "FR", "city": "Lyon", "name": "Jaque", "experience": 11.4 }, {"country": "ES", "city": "Madrid", "name": "Jaque", "experience": 9 }, {"country": "UK", "city": "London", "name": "Henry", "experience": 15 }, {"country": "UK", "city": "London", "name": "James", "experience": 10.9 } ]

result = {}
for key, values in groupby(sorted(data, key=itemgetter('name')), key=itemgetter('name')):
    result[key] = {
        v['country']: {v['city']: [{'experience': v['experience']}]} for v in values
        }

print(result)
# {'Henry': {'UK': {'London': [{'experience': 15}]}}, 'James': {'UK': {'London': [{'experience': 10.9}]}}, 'Jaque': {'FR': {'Lyon': [{'experience': 11.4}]}, 'ES': {'Madrid': [{'experience': 9}]}}, 'Joe': {'US': {'Boston': [{'experience': 100}]}}}

您可以将递归与
itertools一起使用。groupby

from itertools import groupby
def group(d, keys = None):
   key, *keys = keys
   new_d = {a:list(b) for a, b in groupby(sorted(d, key=lambda x:x[key]), key=lambda x:x[key])}
   t = {a:[{c:d for c, d in k.items() if c != key} for k in b] for a, b in new_d.items()}
   return {a:group(b, keys) if not all(len(i) == 1 for i in b) else b for a, b in t.items()}

result = group(data, keys = ['name', 'country', 'city', 'experience'])

输出:

{
  "Henry": {
    "UK": {
        "London": [
            {
                "experience": 15
            }
        ]
    }
  },
  "James": {
    "UK": {
        "London": [
            {
                "experience": 10.9
            }
        ]
    }
  },
  "Jaque": {
    "ES": {
        "Madrid": [
            {
                "experience": 9
            }
        ]
    },
    "FR": {
        "Lyon": [
            {
                "experience": 11.4
            }
        ],
        "Paris": [
            {
                "experience": 20
            }
        ]
    }
  },
  "Joe": {
    "US": {
        "Boston": [
            {
                "experience": 100
            }
        ]
     }
  }
}
{
  "Henry": {
    "UK": {
        "London": [
            {
                "experience": 15
            }
        ]
    }
  },
  "James": {
    "UK": {
        "London": [
            {
                "experience": 10.9
            }
        ]
    }
  },
  "Jaque": {
    "ES": {
        "Madrid": [
            {
                "experience": 9
            }
        ]
    },
    "FR": {
        "Lyon": [
            {
                "experience": 11.4
            }
        ],
        "Paris": [
            {
                "experience": 20
            }
        ]
    }
  },
  "Joe": {
    "US": {
        "Boston": [
            {
                "experience": 100
            }
        ]
     }
  }
}