diff -r ca2a35140e6a Doc/library/heapq.rst --- a/Doc/library/heapq.rst Mon Jan 09 06:17:39 2012 +0000 +++ b/Doc/library/heapq.rst Mon Jan 09 11:27:31 2012 +0100 @@ -81,15 +81,19 @@ The module also offers three general purpose functions based on heaps. -.. function:: merge(*iterables) +.. function:: merge(*iterables [, key]) Merge multiple sorted inputs into a single sorted output (for example, merge timestamped entries from multiple log files). Returns an :term:`iterator` over the sorted values. - Similar to ``sorted(itertools.chain(*iterables))`` but returns an iterable, does - not pull the data into memory all at once, and assumes that each of the input - streams is already sorted (smallest to largest). + *key* specifies a function of one argument that is used to extract a + comparison key from each list element: ``key=str.lower``. The default + value is ``None`` (compare the elements directly). + + Similar to ``sorted(itertools.chain(*iterables), key=key)`` but returns an + iterable, does not pull the data into memory all at once, and assumes that + each of the input streams is already sorted (smallest to largest). .. function:: nlargest(n, iterable, key=None) @@ -289,4 +293,3 @@ backwards, and this was also used to avoid the rewinding time. Believe me, real good tape sorts were quite spectacular to watch! From all times, sorting has always been a Great Art! :-) - diff -r ca2a35140e6a Lib/heapq.py --- a/Lib/heapq.py Mon Jan 09 06:17:39 2012 +0000 +++ b/Lib/heapq.py Mon Jan 09 11:27:31 2012 +0100 @@ -312,7 +312,7 @@ except ImportError: pass -def merge(*iterables): +def merge(*iterables, key=None): '''Merge multiple sorted inputs into a single sorted output. Similar to sorted(itertools.chain(*iterables)) but returns a generator, @@ -327,10 +327,12 @@ h = [] h_append = h.append + key_is_None = key is None for itnum, it in enumerate(map(iter, iterables)): try: next = it.__next__ - h_append([next(), itnum, next]) + v = next() + h_append([v if key_is_None else key(v), itnum, v, next]) except _StopIteration: pass heapify(h) @@ -338,9 +340,12 @@ while 1: try: while 1: - v, itnum, next = s = h[0] # raises IndexError when h is empty + # raises IndexError when h is empty + k, itnum, v, next = s = h[0] yield v - s[0] = next() # raises StopIteration when exhausted + v = next() # raises StopIteration when exhausted + s[0] = v if key_is_None else key(v) + s[2] = v _heapreplace(h, s) # restore heap condition except _StopIteration: _heappop(h) # remove empty iterator diff -r ca2a35140e6a Lib/test/test_heapq.py --- a/Lib/test/test_heapq.py Mon Jan 09 06:17:39 2012 +0000 +++ b/Lib/test/test_heapq.py Mon Jan 09 11:27:31 2012 +0100 @@ -155,8 +155,15 @@ for i in range(random.randrange(5)): row = sorted(random.randrange(1000) for j in range(random.randrange(10))) inputs.append(row) - self.assertEqual(sorted(chain(*inputs)), list(self.module.merge(*inputs))) + self.assertEqual(sorted(chain(*inputs)), + list(self.module.merge(*inputs))) + key = lambda i: abs(i - 500) # something non-monotonous + for row in inputs: + row.sort(key=key) + self.assertEqual(sorted(chain(*inputs), key=key), + list(self.module.merge(*inputs, key=key))) self.assertEqual(list(self.module.merge()), []) + self.assertEqual(list(self.module.merge(key=key)), []) def test_merge_stability(self): class Int(int): diff -r ca2a35140e6a Misc/ACKS --- a/Misc/ACKS Mon Jan 09 06:17:39 2012 +0000 +++ b/Misc/ACKS Mon Jan 09 11:27:31 2012 +0100 @@ -871,6 +871,7 @@ Kevin Samborn Adrian Sampson Ilya Sandler +Simon Sapin Mark Sapiro Ty Sarna Ben Sayer