【问题标题】:Django merge 2 querysets in staggered/alternating fashion?Django以交错/交替的方式合并2个查询集?
【发布时间】:2015-12-07 09:09:47
【问题描述】:

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

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>]

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

[<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 中执行此操作的最佳方法是什么?

【问题讨论】:

    标签: python django


    【解决方案1】:

    您可以同时使用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的结果。

    这会创建一个可迭代的like。

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

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

    【讨论】:

    • 如果 p 和 q 的结果有重叠,您建议如何消除重复?
    • @w-- 这不是原始问题的一部分,所以最好提出一个新问题。
    • 很酷,谢谢。我在这里创建了一个新问题:stackoverflow.com/questions/45834009/…
    猜你喜欢
    • 1970-01-01
    • 2016-02-29
    • 2022-11-08
    • 2015-06-23
    • 2020-04-27
    • 2018-08-02
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多