Django以交错/交替方式合并2个查询集?

时间:2015-09-10 22:40:42

标签: python django

在我的Django应用程序中,我有2个相同对象的查询集。我知道我可以使用itertools和链合并2个查询集,如下所示:

PhotoImage

但是这会输出一个新的查询集,其中整个第一个跟随整个第二个,如下所示:

from itertools import chain
list(chain(first_queryset, second_queryset))

但是,我真的需要一个在每个查询集之间交替的输出,而不是仅仅在第一个查询集的末尾附加整个第二个查询集,如下所示:

[<first_queryset_1st_instance>, <first_queryset_2nd_instance>,       <first_queryset_3rd_instance>, <second_queryset_1st_instance>, <second_queryset_2nd_instance>, <second_queryset_3rd_instance>]

在python / django中我能做到的最好的方法是什么?

1 个答案:

答案 0 :(得分:3)

您可以使用zip_longestchainfilter一起获得所需的结果。

让我们调用查询集pq。然后你会这样做:

# Python 3.x
from itertools import chain, zip_longest
combined = list(filter(lambda x: x is not None, chain(*zip_longest(p, q))))

# Python 2.7
from itertools import chain, ifilter, izip_longest
combined = list(ifilter(lambda x: x is not None, chain(*izip_longest(p, q))))

让我们解释它是如何运作的。首先,zip_longest(Python 2中的izip_longest)将查询集压缩在一起。您需要zip_longest而不是zip,以便在较短的查询集完成后继续输出。

这会创建一个像:

这样的迭代
((p[0], q(0)), (p[1], q[1]), (p[2], q[2]), ..., (p[9], q[9]), (p[10], None))

请注意,这是一个可迭代的元组,但您需要一个平面列表。接下来我们使用chain,使用*运算符解包zip_longest的结果。

这会创建一个像。

这样的迭代
(p[0], q[0], p[1], q[1], ..., p[9], q[9], p[10], None)

这几乎是我们想要的,但如果一个查询集比另一个更短,我们最后得到None。我们可以使用filter(Python 2中的ifilter)来消除它们。