最有效的方法来过滤queryset中的最低值

时间:2014-06-02 03:56:36

标签: python django

假设:

some_list = SomeClass.objects.filter(something=something).order_by('-X','-Y')

英文版:some_listSomeClass个对象的已过滤列表,按两个值排序,先是X,然后是Y

如果我想将列表中的条目数限制为某个值Z,我可以这样做:

final_list = some_list[:Z]

但是,如果我想将条目数量限制为某个值,但是在我之前将“截止条目”随机化呢?我很难描述,所以一个例子:

SC  X  Y
 A  2  3
 B  1  2
 C  1  1
 D  1  1
 E  1  1
 F  1  0
 G  0  3

如果Z=3,则使用我的方法final_list = (A,B,C)。我想要的是final_list包括A和B,因为它们明显高于其他人(A的X比其他任何人都大,B与第二大X并列,但是Y更大),但是看作切割 - off将在C为X=1,Y=1,并且有两个OTHER对象与C“绑定”,第三个插槽可以是C,D或E.

我可以手动拉some_list并检查值并开始将它们放入final_list直到我击中Z,但我希望有更好的方法我不知道。因为,代码行数较少,处理能力较低等等。

因此,对于这个例子,我希望其中一个输出是随机的:

final_list = (A, B, C)
final_list = (A, B, D)
final_list = (A, B, E)

如果Z = 4,我希望其中一个输出:

final_list = (A, B, C, D)
final_list = (A, B, C, E)
final_list = (A, B, D, C)
final_list = (A, B, D, E)
final_list = (A, B, E, C)
final_list = (A, B, E, D)

希望这很清楚。

1 个答案:

答案 0 :(得分:0)

你可以做一些简单的事情,例如用X和Y的平均值注释你的查询,然后选择高于平均值的值。例如,像:

some_list = SomeClass.objects.filter(
                something=something
            ).annotate(
                average_x=Avg("X"), average_y=Avg("Y")
            ).order_by(
                '-X','-Y'
            )

def passes_threshold(x, y, avgx, avgy):
    '''Simplistic function to check if a combination of X & Y is better than
    another. Update to better suit your context.
    '''
    return (x + y) > (avgx + avgy)

# You could use filter instead, if you want all values from the list matching,
# but if you want just until the first few that match,
required_list = itertools.takewhile(passes_threshold, some_list)