Pythonic List Iteration

时间:2013-08-08 10:28:01

标签: python django iteration

我有一个Django Querysets列表,我想将它组合成一个Query。合并两个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方式执行上述操作吗?

1 个答案:

答案 0 :(得分: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

对于包含4个元素的qs_list,可归结为:

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]

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

请注意,您对if final_qs not in locals()的使用非常简单;不要那样做。您可以使用来自final_qs的初始qs_list[0]来编写循环:

final_qs = qs_list[0]
for qs in qs_list[1:]:
    final_qs |= qs