summaryrefslogtreecommitdiffstats
path: root/Lib/heapq.py
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2007-02-19 04:08:43 (GMT)
committerRaymond Hettinger <python@rcn.com>2007-02-19 04:08:43 (GMT)
commit00166c5532fc7562c07383a0ae2985b3ffaf253a (patch)
tree6f9c77ecb9639ad781c83d22d63e8014a71d5a76 /Lib/heapq.py
parentd6fc72a5ae27048dae56c773896ccbd6152d9b9b (diff)
downloadcpython-00166c5532fc7562c07383a0ae2985b3ffaf253a.zip
cpython-00166c5532fc7562c07383a0ae2985b3ffaf253a.tar.gz
cpython-00166c5532fc7562c07383a0ae2985b3ffaf253a.tar.bz2
Add merge() function to heapq.
Diffstat (limited to 'Lib/heapq.py')
-rw-r--r--Lib/heapq.py42
1 files changed, 40 insertions, 2 deletions
diff --git a/Lib/heapq.py b/Lib/heapq.py
index 753c3b7..b56d0f9 100644
--- a/Lib/heapq.py
+++ b/Lib/heapq.py
@@ -126,8 +126,8 @@ Believe me, real good tape sorts were quite spectacular to watch!
From all times, sorting has always been a Great Art! :-)
"""
-__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest',
- 'nsmallest']
+__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge',
+ 'nlargest', 'nsmallest']
from itertools import islice, repeat, count, imap, izip, tee
from operator import itemgetter, neg
@@ -308,6 +308,41 @@ try:
except ImportError:
pass
+def merge(*iterables):
+ '''Merge multiple sorted inputs into a single sorted output.
+
+ Similar to sorted(itertools.chain(*iterables)) but returns an iterable,
+ does not pull the data into memory all at once, and reduces the number
+ of comparisons by assuming that each of the input streams is already sorted.
+
+ >>> list(merge([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 = heappop, _siftup, StopIteration
+
+ h = []
+ h_append = h.append
+ for it in map(iter, iterables):
+ try:
+ next = it.next
+ h_append([next(), next])
+ except _StopIteration:
+ pass
+ 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
+
# Extend the implementations of nsmallest and nlargest to use a key= argument
_nsmallest = nsmallest
def nsmallest(n, iterable, key=None):
@@ -341,3 +376,6 @@ if __name__ == "__main__":
while heap:
sort.append(heappop(heap))
print sort
+
+ import doctest
+ doctest.testmod()