Sorry about the cut-and-paste error. Corrected below. Also, I believe my code is equivalent to Thomas'.<br><br>-Damon<br><br><br><div class="gmail_quote">On Wed, Apr 14, 2010 at 9:29 AM, Damon McCormick <span dir="ltr"><<a href="mailto:damonmc@gmail.com">damonmc@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Keeping your original approach, you could define a function like this:<br><br>def next_or_none_pair (itr):<br>
def result_func ():<br> try:<br> return itr.next()<br> except StopIteration:<br> return (None, None)<br>
return result_func<br><br>and then replace your current definitions of xnext and ynext by the following:<br><br> xnext = next_or_none_pair(itertools.groupby(xs, grouper))<br> ynext = next_or_none_pair(itertools.groupby(ys, grouper))<br>
<br>The condition of your while loop is already set up to exit when either x or y is None (a condition which, I believe, is currently never True, since the loop ends when StopIteration is thrown).<br><br>So the only other modification you'd need is that your comparisions between x and y need to handle None:<br>
<br> elif y is None or x < y:<br> yield list(xgroup), None<br> x, xgroup = xnext()<br> elif x is None or x > y:<br> yield (None, list(ygroup))<br> y, ygroup = ynext()<br>
<br>So the entire thing would look like this:<br><br></blockquote><div> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
import itertools<br><br><br>def next_or_none_pair (itr):<br> def result_func ():<br> try:<br> return itr.next()<br> except StopIteration:<br> return (None, None)<br> return result_func<div class="im">
<br>
<br>def as_pairs (xs, ys, grouper=lambda _: _):<br> """ <br></div><div class="im"> >>> aordered = [1, 1, 2, 4, 6, 8, 9] <br>
>>> bordered = [1, 3, 4, 5, 6, 7, 8] <br> >>> for a, b in as_pairs(aordered, bordered): <br> ... a, b <br>
</div>
([1, 1], [1]) <br> ([2], None) <br> (None, [3]) <br>
([4], [4]) <br> (None, [5]) <br> ([6], [6]) <br>
(None, [7]) <br> ([8], [8]) <br> ([9], None) <br>
<div class="im">
"""<br> # assume xs and ys are sorted. <br></div> xnext = next_or_none_pair(itertools.groupby(xs, grouper))<br> ynext = next_or_none_pair(itertools.groupby(ys, grouper))<br>
x, xgroup = xnext()<br> y, ygroup = ynext()<div class="im"><br> while x or y:<br> if x == y:<br> yield list(xgroup), list(ygroup)<br></div> x, xgroup = xnext()<br> y, ygroup = ynext()<br>
elif y is None or x < y:<br>
yield list(xgroup), None<br> x, xgroup = xnext()<br> elif x is None or x > y:<br> yield (None, list(ygroup))<br> y, ygroup = ynext()<br> else:<br> assert False<br>
<br>if __name__ == "__main__":<br> import doctest<br> doctest.testmod()<div><div></div><div class="h5"><br><br><br><br><br><div class="gmail_quote">On Wed, Apr 14, 2010 at 9:04 AM, Brent Pedersen <span dir="ltr"><<a href="mailto:bpederse@gmail.com" target="_blank">bpederse@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>On Wed, Apr 14, 2010 at 8:20 AM, Brent Pedersen <<a href="mailto:bpederse@gmail.com" target="_blank">bpederse@gmail.com</a>> wrote:<br>
> hi, in trying to write a func that does a kind of merging of 2 sorted lists,<br>
> i've come up with a fairly simple implementation that "almost works":<br>
> <a href="http://gist.github.com/365485" target="_blank">http://gist.github.com/365485</a><br>
><br>
> but it hits StopIteration before returning the last value ([9], None)<br>
> i can wrap the whole thing in a bunch more if statements, i've tried<br>
> heapq.merge, but cant find a nice solution.<br>
><br>
> any ideas? i think it's an interesting problem.<br>
> -brent<br>
><br>
<br>
</div>i should add the for my real use-case, the iterables going in will not<br>
be lists, they'll be lazily generated, and very large, so<br>
i dont want to read them into memory to get the last element or slice them.<br>
<div><div></div><div>______________________________<br></div></div></blockquote></div>
</div></div></blockquote></div><br>