本文介绍了Django以交错/交替的方式合并2个查询集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Django应用中,我有两个 same 对象的查询集.我知道我可以像这样使用itertools和chain合并2个查询集:

In my Django app I have 2 querysets of the same object. I know I can merge 2 querysets using itertools and chain like so:

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

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

But this outputs a new queryset where the entire first one is followed by the entire second one like so:

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

但是,我确实需要一个在每个查询集之间交替的输出,而不是像这样在整个第一个查询集的末尾附加整个第二个查询集:

However, I really need an output that is alternating between each queryset instead of just appending the entire second queryset at the end of the first one like so:

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

在python/django中执行此操作的最佳方法是什么?

What's the best way I can do this in python/django?

推荐答案

您可以使用 zip_longest 过滤器 .

You can get the result you need using zip_longest, chain and filter together.

让我们将查询集称为 p q .然后您会这样做:

Lets call the querysets p and q. Then you would do:

# 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 ,以便在较短的查询集完成后继续输出.

Let's explain how it works. First, zip_longest (izip_longest in Python 2) zips the querysets together. You want zip_longest instead of zip, so that the output continues after the shorter queryset has finished.

这将创建一个可迭代的内容,例如:

This creates an iterable like:

((p[0], q(0)), (p[1], q[1]), (p[2], q[2]), ..., (p[9], q[9]), (p[10], None))

请注意,这是一个可重复的元组,但是您需要一个平面列表.因此,接下来我们使用 chain ,使用 * 运算符解压缩 zip_longest 的结果.

Note this is an iterable of tuples, but you want a flat list. So next we use chain, using the * operator to unpack the result of zip_longest.

这会创建一个可迭代的对象.

This creates an iterable like.

(p[0], q[0], p[1], q[1], ..., p[9], q[9], p[10], None)

这几乎是我们想要的,但是如果一个查询集比另一个查询集短,我们最后将得到 None .我们可以使用 filter (在Python 2中为 ifilter )摆脱它们.

That's almost what we want, but we've got Nones at the end if one queryset is shorter than the other. We can get rid of them with filter (ifilter in Python 2).

这篇关于Django以交错/交替的方式合并2个查询集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-24 17:14