使用值过滤器对对象进行优先级排序

2024-04-19 00:28:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个有趣的编程问题,我肯定有很多非常有趣的解决方案,我希望有人有一些洞察到一个好的方向,我可以采取。你知道吗

我在Django工作,我有一个对象查询集和一组过滤器。我想找到一个子集的对象生存的所有过滤器,但这并不总是可能的,所以我想秩序的queryset,使对象生存的最重要的过滤器之前总是得到过滤掉。我为每个过滤器定义了一个重要级别。你知道吗

所以,在一个抽象的层次上,给定一组对象和一组加权约束,我想要一个按权重排序的对象列表。你知道吗

例如, 给定一组单词:

{'Almond', 'Red', 'Apple', 'Gargle', 'Anyone'}

以及一组值过滤器:

- Starts with A, worth 10 points

- Ends with E, worth 5 points

- 6 letters long, worth 3 points

返回以下数组,其中包含关联的分数:

[['Anyone',18],['Apple',15],['Almond', 13],['Gargle',8],['Red',0]]

因为这些是Django中的对象和过滤器,所以我也希望尽可能地使用queryset函数,而不是使用循环来提高运行时和复杂性(我使用的是PostgreSQL,所以任何特定于PostgreSQL的解决方案都可以)。 因此,基本上,如果我有n个对象和f个过滤器,我希望获得比O(nf+nlogn)更好的复杂性,或者至少优化Django的解决方案。你知道吗


Tags: 对象django过滤器applepostgresqlwithred解决方案
1条回答
网友
1楼 · 发布于 2024-04-19 00:28:28
from django.db.models import CharField, IntegerField, Case, When, Q
from django.db.models.functions import Length

# You can register function as a transform
CharField.register_lookup(Length, 'length')

filters = [
    (Q(name__startswith='A'), 10),
    (Q(name__endswith='E'), 5),
    (Q(name__length=6), 3),
]

Item.objects.annotate(
    # sum, not Sum
    tot_score=sum(Case(When(filter, then=score),
                       default=0,
                       output_field=IntegerField())
                  for filter, score in filters)
).values_list('name', 'tot_score').order_by('-tot_score')

Conditional Expressions。你知道吗

相关问题 更多 >