无论如何将数据结构化为有效的 python 列表或元组

Is there anyway to structure data to python list or tuple that is efficient

有什么方法可以构造从数据库中获取的数据,目前我使用 append 但是当获取的数据超过 1k 时它变得很慢

courses = []
for i in departments:
    for course in i.course_set.all():
        course = [course.name]
        info_list = []
        for year in range(1, 5):
            info = [year, (['Regular'], ['Irregular'])]
            info_list.append(info)

            count = 0
            for gender in ['male', 'female']:
                regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
                irregular = students.filter(year_level=year, status='irregular', course=course, gender=gender).count()

                info[1][0].append(regular)
                info[1][1].append(irregular)

            regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
            irregular = students.filter(year_level=year,status='irregular', course=course, gender=gender).count()

            info[1][0].append(regular)
            info[1][1].append(irregular)
            info[1][2].append(cross)

            total = regular + irregular
            count += total
            info.append(count)

        program.append(info_list)

        male = students.filter(gender='male', course=course).count()
        female = students.filter(gender='female', course=course).count()
        overall = students.filter(gender=None), course=course).count()

        program.append(["", "Total", "", male, female, overall, overall])
        courses.append(program)

我不确定是追加还是查询在数据库上多次命中。拿到之后我会用它来输出数据到pdf表格

您遇到的低效率不是来自您用来处理数据的 Python 结构或过程,而是来自您使用多个循环和查询来使用 django 获取数据的方式。我可能不完全了解您正在处理的数据,但据我所知,您实际上是在尝试对每个类别(性别、状态、课程等)的学生总数进行细分,然后获取小计和总体总数。

更好的方法是只使用一两个 Django 查询并让数据库为您完成大部分工作。然后可以在python内存中处理结果得到小计。

例如,假设您需要按性别、状态、课程名称和年份细分学生人数。您可以一次调用从数据库中获取此数据:

results = list(Student.objects.values('year_level', 'status', 'course__name', 'gender').annotate(total=Count('id')))

results 将包含字典列表,如下所示:

result = [
    {'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'female', 'total': 2}, 
    {'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'male', 'total': 2}, 
    {'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'female', 'total': 1}, 
    {'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'male', 'total': 1}, 
    {'year_level': 3, 'status': 'regular', 'course__name': 'Course C', 'gender': 'male', 'total': 1}
]

因此,对于分类中的每个变体,您都会得到一个总计数。然后,如果您想将这些组合成小计,您可以使用 reduce 从结果中快速获取这些:

male_students = reduce(
   lambda total, result: total + (result['total'] if result['gender'] == 'male' else 0),
   results, initial=0
)
female_students = reduce(
   lambda total, result: total + (result['total'] if result['gender'] == 'female' else 0),
   results, initial=0
)
all_students = reduce(lambda total, result: total + result['total'], results, 0)

另一个按年份细分的例子:

students_by_year = {1: {}, 2: {}, 3:{}, 4:{}}
for year in range(1, 5):
    students_by_year[year]['male'] = reduce(
        lambda total, result: total + (result['total']
            if result['gender'] == 'male' and result['year_level'] == year else 0
        ), results, initial=0)
    students_by_year[year]['female'] = reduce(
        lambda total, result: total + (result['total']
            if result['gender'] == 'female' and result['year_level'] == year else 0
        ), results, initial=0)

针对一个或多个特定条件修改 lambda 函数中的“if”条件将为您提供小计。

此时,无论您使用何种技术处理结果,您在 python 的结果中使用词典列表所做的工作和处理方式都会更快。你效率低下的根源是你循环遍历 django 查询结果并对数据库进行多次查询的方式。

如果您的数据集非常非常大(可能有几十万学生),那么针对您需要的特定小计单独构建 Django 查询会变得更加高效,例如:

male_students_by_year = list(Student.objects.filter(gender='male').values('year_level').annotate(total=Count('id')))

以上会给你这样的结果:

[ 
   {'year_level': 1, 'total': 2}, 
   {'year_level': 2, 'total': 1}, 
   {'year_level': 3, 'total': 1}
]

希望这对您有所帮助,如果以上任何内容需要澄清,请告诉我。