Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>import itertools as it import heapq import pprint def imerge(*iterables): ''' http://code.activestate.com/recipes/491285-iterator-merge/ Author: Raymond Hettinger Merge multiple sorted inputs into a single sorted output. Equivalent to: sorted(itertools.chain(*iterables)) &gt;&gt;&gt; list(imerge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] ''' heappop, siftup, _StopIteration = heapq.heappop, heapq._siftup, StopIteration h = [] h_append = h.append for it in map(iter, iterables): try: next = it.next h_append([next(), next]) except _StopIteration: pass heapq.heapify(h) while 1: try: while 1: v, next = s = h[0] # raises IndexError when h is empty yield v s[0] = next() # raises StopIteration when exhausted siftup(h, 0) # restore heap condition except _StopIteration: heappop(h) # remove empty iterator except IndexError: return a = ( 2, 3, 4, ) b = (1, ) c = ( 5,) d = (1, 3, 5,) def tag(iterator,val): for elt in iterator: yield elt,val def expand(group): dct=dict((tag,val)for val,tag in group) result=[dct.get(tag,None) for tag in range(4)] return result pprint.pprint( [ expand(group) for key,group in it.groupby( imerge(*it.imap(tag,(a,b,c,d),it.count())), key=lambda x:x[0] )]) </code></pre> <p>Explanation:</p> <ul> <li>Life would be easier if we mergesort the iterators. This can be done with <code>imerge</code></li> <li><p><code>itertools.groupby</code> gives us the desired grouping if we feed it the<br> result from <code>imerge</code>. The rest is just niggling details. </p> <pre><code>pprint.pprint( [ list(group) for key,group in it.groupby( imerge(a,b,c,d)) ] ) # [[1, 1], [2], [3, 3], [4], [5, 5]] </code></pre></li> <li>From the output above, it is clear we need to keep track of the source of each value -- (did the value come from <code>a</code>, or <code>b</code>, etc.). That way we can pad the output with <code>None</code>s in the right places.</li> <li><p>To do that I used <code>it.imap(tag,(a,b,c,d),it.count())</code>. <code>tag(a)</code> returns an iterator which yields values from <code>a</code> along with a counter value.</p> <pre><code>&gt;&gt;&gt; list(tag(a,0)) # [(2, 0), (3, 0), (4, 0)] </code></pre></li> <li><p>The output now looks like this:</p> <pre><code>pprint.pprint( [ list(group) for key,group in it.groupby( imerge(*it.imap(tag,(a,b,c,d),it.count())), key=lambda x:x[0] )]) # [[(1, 1), (1, 3)], [(2, 0)], [(3, 0), (3, 3)], [(4, 0)], [(5, 2), (5, 3)]] </code></pre></li> <li>Finally, we use <code>expand(group)</code> to change <code>[(1, 1), (1, 3)]</code> into <code>[None, 1, None, 1]</code>.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload