1

我有一个 Django 查询集列表,我想将它们组合成一个查询。合并两个 Queryset 的标准方法是执行操作:newQ = Q1 | Q2,我想对列表的所有元素执行该操作以形成单个 Queryset 对象。

使用 for 循环非常简单,例如:

for qs in qs_list:
    if final_qs not in locals():
        final_qs = qs
    else:
        final_qs = final_qs | qs  

鉴于 python 的奇妙之处,感觉好像可能有某种内置函数可以为您执行此操作。然而,我浏览了这个itertools库,并没有发现任何东西可以简化这个操作。

所以我的问题是,是否有更 Pythonic 的方式来执行上述操作?

4

1 回答 1

5

是的,该函数称为functools.reduce(). 使用它operator.or_()

import operator
from functools import reduce

final_qs = reduce(operator.or_, qs_list)

reduce()将第一个值qs_list传递给 ,将它们传递给第一个参数,operator.or_,有效地执行qs_list[0] | qs_list[1]。然后它获取该结果,加上下一个值qs_list并再次应用第一个参数,依此类推,直到qs_list完成。

对于qs_list4 个元素,归结为:

or_(or_(or_(qs_list[0], qs_list[1]), qs_list[2]), qs_list[3])

或相当于:

qs_list[0] | qs_list[1] | qs_list[2] | qs_list[3]

但 reduce 适用于qs_list> 0 的任何长度(对于长度为 1 的列表,返回第一个值而不应用第一个参数)。

请注意,您的使用if final_qs not in locals()是非常不符合标准的;永远不要那样做。您可以使用初始final_qsfromqs_list[0]来编写循环:

final_qs = qs_list[0]
for qs in qs_list[1:]:
    final_qs |= qs
于 2013-08-08T10:30:17.327 回答