python 如何用itertools中的groupby对字典列表进行分组?

tct7dpnv  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(190)

我正在用python创建一个应用程序,我使用postgresql数据库,用tortoise-orm进行查询。在数据库中有几个表,但是对于问题我有:"project","assignment",它们之间是一对多的关系,我需要根据某个参数过滤"assignments"(这个问题无关紧要),然后我想把它们分组,在json中返回,这就是我要实现的函数:

from datetime import date
from itertools import groupby

from app.models.assignment import Assignment

async def calendar(self, start_filter: date, final_filter:date):
        assignments = await self.model.filter(
            start_date__lte=final_filter,
            final_date__gte=start_filter
        ).prefetch_related("collaborator__job", "project").all()
        grouped_assignments = {}
        for project_id, project_assignments in groupby(assignments, lambda x: x.project_id):
            grouped_assignments[project_id] = list(project_assignments)
        return grouped_assignments

为了直接解决这个问题,在作业中应用了过滤器,我得到了这样的结果:

[
  {
    "name": "tarea de backend",
    "start_date": "2023-02-10",
    "final_date": "2023-02-20",
    "id": 1,
    "collaborator_id": 1,
    "project_id": 1
  },
  {
    "name": "tarea de backend",
    "start_date": "2023-02-10",
    "final_date": "2023-02-25",
    "id": 2,
    "collaborator_id": 2,
    "project_id": 1
  },
  {
    "name": "tarea de data science",
    "start_date": "2023-02-10",
    "final_date": "2023-02-20",
    "id": 3,
    "collaborator_id": 3,
    "project_id": 1
  },
  {
    "name": "tarea de data science",
    "start_date": "2023-02-10",
    "final_date": "2023-02-25",
    "id": 4,
    "collaborator_id": 4,
    "project_id": 1
  },
  {
    "name": "tarea de frontend",
    "start_date": "2023-02-20",
    "final_date": "2023-02-25",
    "id": 5,
    "collaborator_id": 5,
    "project_id": 1
  },
  {
    "name": "tarea de frontend",
    "start_date": "2023-02-20",
    "final_date": "2023-02-25",
    "id": 6,
    "collaborator_id": 5,
    "project_id": 2
  },
  {
    "name": "tarea de frontend",
    "start_date": "2023-02-20",
    "final_date": "2023-02-27",
    "id": 7,
    "collaborator_id": 6,
    "project_id": 1
  },
  {
    "name": "tarea de frontend",
    "start_date": "2023-02-20",
    "final_date": "2023-02-27",
    "id": 8,
    "collaborator_id": 6,
    "project_id": 2
  },
  {
    "name": "Tarea de backend",
    "start_date": "2023-03-11",
    "final_date": "2023-03-17",
    "id": 9,
    "collaborator_id": 1,
    "project_id": 2
  }
]

现在只有两个项目(Project_id = 1和Project_id = 2),我想要的是所有的任务都根据每个project_id分组,所以在json中我期望如下所示:

{
  "1": [
    {
      "start_date": "2023-02-20",
      "collaborator_id": 6,
      "final_date": "2023-02-27",
      "id": 7,
      "name": "tarea de frontend",
      "project_id": 1
    }
  ],
  "2": [
    {
      "start_date": "2023-02-20",
      "collaborator_id": 6,
      "final_date": "2023-02-27",
      "id": 8,
      "name": "tarea de frontend",
      "project_id": 2
    },
    {
      "start_date": "2023-03-11",
      "collaborator_id": 1,
      "final_date": "2023-03-17",
      "id": 9,
      "name": "Tarea de backend",
      "project_id": 2
    }

]}
实际上上面的json就是我得到的,由于某些原因我没有得到每个项目的所有任务(我测试的日期过滤器返回了上面我放置的9个赋值语句的列表)我看代码的方式是,在for循环中,我迭代赋值语句,并根据它们的project_id对它们进行分组,group_by应该只返回两个分组,一个用于project_id = 1,另一个用于project_id = 2,但是它似乎对相同的project_id进行了不同的分组。我不知道我做错了什么,或者我误解了groupby的工作原理。

o7jaxewo

o7jaxewo1#

在最后一个循环之前,对“赋值”进行排序,如下所示:

assignments = sorted(assignments, key=lambda x:x["project_id"]) # add this line
grouped_assignments = {}
for project_id, project_assignments in groupby(assignments, lambda x: x["project_id"]):
    grouped_assignments[project_id] = list(project_assignments)

我还将x.project_id切换为x["project_id"]

相关问题