假设:
some_list = SomeClass.objects.filter(something=something).order_by('-X','-Y')
英文版:some_list
是SomeClass
个对象的已过滤列表,按两个值排序,先是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)
希望这很清楚。
答案 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)