在我的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中我能做到的最好的方法是什么?
答案 0 :(得分:3)
您可以使用zip_longest
,chain
和filter
一起获得所需的结果。
让我们调用查询集p
和q
。然后你会这样做:
# 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
)来消除它们。