2015-09-10 2 views
3

В моем приложении Django у меня есть 2 запроса того же объекта. Я знаю, что могу объединить 2 querysets используя itertools и цепь следующим образом:Django объединяет 2 запроса в шахматном порядке/чередующемся режиме?

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

Но это выводит новый 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>] 

Однако я действительно нужен вывод, что чередующиеся между каждым QuerySet вместо того, чтобы просто прилагая всю вторую QuerySet в конце первого типа так:

[<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?

ответ

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 (izip_longest в Python 2) застегивает наборы запросов вместе. Вы хотите, чтобы 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 S в конце концов, если один QuerySet короче другой. Мы можем избавиться от них с помощью filter (ifilter в Python 2).

+0

Если есть совпадение между результатами в p и q, что вы рекомендуете устранять дубликаты? –

+0

@ w-- это не часть исходной проблемы, поэтому было бы лучше задать новый вопрос. – Alasdair

+0

круто спасибо. Здесь я задал новый вопрос: https://stackoverflow.com/questions/45834009/django-merge-2-querysets-in-staggered-alternating-fashion-without-duplicates –

Смежные вопросы