Python 将有序dict列表转换为嵌套列表

Python 将有序dict列表转换为嵌套列表,python,list,dictionary,Python,List,Dictionary,我有一个有序的dict列表,其中包含数据中的一些重复ID。。像这样的 [OrderedDict([('caseId', 20), ('userId', 1), ('emailStatus', 21)]), OrderedDict([('caseId', 20), ('userId', 1), ('emailStatus', 20)]), OrderedDict([('caseId', 18), ('userId', 4), ('emailStatus', 21)]), Ordered

我有一个有序的dict列表,其中包含数据中的一些重复ID。。像这样的

[OrderedDict([('caseId', 20), ('userId', 1), ('emailStatus', 21)]), 
 OrderedDict([('caseId', 20), ('userId', 1), ('emailStatus', 20)]), 
 OrderedDict([('caseId', 18), ('userId', 4), ('emailStatus', 21)]), 
 OrderedDict([('caseId', 19), ('userId', 3), ('emailStatus', 21)]), 
 OrderedDict([('caseId', 18), ('userId', 1), ('emailStatus', 20)]),
 OrderedDict([('caseId', 20), ('userId', 3), ('emailStatus', 21)]),
 OrderedDict([('caseId', 18), ('userId', 4), ('emailStatus', 20)]), 
 OrderedDict([('caseId', 19), ('userId', 1), ('emailStatus', 20)])]
我想得到一个嵌套列表的列表,类似这样的东西

[{
"caseId": "20",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      },
      {
      "emailStatus" : "21"
      }

    ]
  },
    {
    "userId": "3",
    "emailStatus": [
      {
      "emailStatus" : "21"
      }

    ]

  }
]
},
{
"caseId": "19",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      }
    ]

  },
    {
    "userId": "3",
    "emailStatus": [
      {
      "emailStatus" : "21"
      }

    ]

  }
]
},
{
"caseId": "18",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      }
    ]

  },
    {
    "userId": "4",
    "emailStatus": [
      {
      "emailStatus" : "20"
      },
      {
      "emailStatus" : "21"
      }

    ]

  }
]
}
]
呈现这样的嵌套列表

[{
"caseId": "20",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      },
      {
      "emailStatus" : "21"
      }

    ]
  },
    {
    "userId": "3",
    "emailStatus": [
      {
      "emailStatus" : "21"
      }

    ]

  }
]
},
{
"caseId": "19",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      }
    ]

  },
    {
    "userId": "3",
    "emailStatus": [
      {
      "emailStatus" : "21"
      }

    ]

  }
]
},
{
"caseId": "18",
"users": [
  {
    "userId": "1",
    "emailStatus": [
      {
      "emailStatus" : "20"
      }
    ]

  },
    {
    "userId": "4",
    "emailStatus": [
      {
      "emailStatus" : "20"
      },
      {
      "emailStatus" : "21"
      }

    ]

  }
]
}
]

我试图通过迭代这两个列表来实现这一点,但不知道如何保存上一个和下一个记录以及相同的数据。。那太令人困惑了。。如果有人能给我一个开始,我可以迭代我的名单,这将是非常感谢你

多谢

更新的问题


首先,您可以使用循环和
dict.setdefault
将数据分组到嵌套的dict中:

temp = {}
for d in lst:
    temp.setdefault(d["caseId"], {}).setdefault(d["userId"], []).append(d["emailStatus"])
print(temp)
# {18: {1: [20], 4: [21, 20]}, 19: {1: [20], 3: [21]}, 20: {1: [21, 20], 3: [21]}}
或使用
集合。defaultdict

temp = defaultdict(lambda: defaultdict(list))
for d in lst:
    temp[d["caseId"]][d["userId"]].append(d["emailStatus"])
然后,使用嵌套的混合dict和列表理解来聚合最终结果:

res = [{"caseId": case, "users": [{"userId": user, "emailStatus": [{"emailStatus": s} for s in status]} 
                                  for user, status in users.items()]} 
       for case, users in temp.items()]
print(res)
# [{'caseId': 18, 'users': [{'userId': 1, 'emailStatus': [{'emailStatus': 20}]}, {'userId': 4, 'emailStatus': [{'emailStatus': 21}, {'emailStatus': 20}]}]},
#  {'caseId': 19, 'users': [{'userId': 1, 'emailStatus': [{'emailStatus': 20}]}, {'userId': 3, 'emailStatus': [{'emailStatus': 21}]}]},
#  {'caseId': 20, 'users': [{'userId': 1, 'emailStatus': [{'emailStatus': 21}, {'emailStatus': 20}]}, {'userId': 3, 'emailStatus': [{'emailStatus': 21}]}]}]

附录:输入中的
orderedict
实际上没有任何效果,但是如果您想对结果中的dict进行排序,只需使用
setdefault(…,orderedict())
并使用
orderedict([(key,val),…])
而不是最终的dict理解。真是让人吃惊。。这是极好的解决方案,有很好的解释。谢谢大家。@tobias_s如果我们需要将用户名和userId分组,在下面的行temp.setdefault(d[“caseId”],{})中更改位置。setdefault(d[“userId”],[])。append(d[“emailStatus”])@NullPointer你是什么意思?我在你的口述中没有看到“用户名”字段。假设存在这样一个字段,是否要将这两个字段合并为一个键?在这种情况下,请尝试
…setdefault(d[“caseId”]+d[“userName”])…
或类似的方法。没有更多信息很难说。我应该创建另一个问题还是更新此问题以了解更多详细信息?