3👍
You can get the result you need using zip_longest
, chain
and filter
together.
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))))
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))
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)
That’s almost what we want, but we’ve got None
s at the end if one queryset is shorter than the other. We can get rid of them with filter
(ifilter
in Python 2).
Source:stackexchange.com