Kaydet (Commit) ca516d21 authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Fix stability of heapq's nlargest() and nsmallest().

üst d0f67293
...@@ -130,7 +130,7 @@ __all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest', ...@@ -130,7 +130,7 @@ __all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest',
'nsmallest'] 'nsmallest']
from itertools import islice, repeat, count, imap, izip, tee from itertools import islice, repeat, count, imap, izip, tee
from operator import itemgetter from operator import itemgetter, neg
import bisect import bisect
def heappush(heap, item): def heappush(heap, item):
...@@ -315,8 +315,6 @@ def nsmallest(n, iterable, key=None): ...@@ -315,8 +315,6 @@ def nsmallest(n, iterable, key=None):
Equivalent to: sorted(iterable, key=key)[:n] Equivalent to: sorted(iterable, key=key)[:n]
""" """
if key is None:
return _nsmallest(n, iterable)
in1, in2 = tee(iterable) in1, in2 = tee(iterable)
it = izip(imap(key, in1), count(), in2) # decorate it = izip(imap(key, in1), count(), in2) # decorate
result = _nsmallest(n, it) result = _nsmallest(n, it)
...@@ -328,10 +326,8 @@ def nlargest(n, iterable, key=None): ...@@ -328,10 +326,8 @@ def nlargest(n, iterable, key=None):
Equivalent to: sorted(iterable, key=key, reverse=True)[:n] Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
""" """
if key is None:
return _nlargest(n, iterable)
in1, in2 = tee(iterable) in1, in2 = tee(iterable)
it = izip(imap(key, in1), count(), in2) # decorate it = izip(imap(key, in1), imap(neg, count()), in2) # decorate
result = _nlargest(n, it) result = _nlargest(n, it)
return map(itemgetter(2), result) # undecorate return map(itemgetter(2), result) # undecorate
......
...@@ -104,20 +104,20 @@ class TestHeap(unittest.TestCase): ...@@ -104,20 +104,20 @@ class TestHeap(unittest.TestCase):
self.assertEqual(heap_sorted, sorted(data)) self.assertEqual(heap_sorted, sorted(data))
def test_nsmallest(self): def test_nsmallest(self):
data = [random.randrange(2000) for i in range(1000)] data = [(random.randrange(2000), i) for i in range(1000)]
f = lambda x: x * 547 % 2000 for f in (None, lambda x: x[0] * 547 % 2000):
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100): for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
self.assertEqual(nsmallest(n, data), sorted(data)[:n]) self.assertEqual(nsmallest(n, data), sorted(data)[:n])
self.assertEqual(nsmallest(n, data, key=f), self.assertEqual(nsmallest(n, data, key=f),
sorted(data, key=f)[:n]) sorted(data, key=f)[:n])
def test_nlargest(self): def test_nlargest(self):
data = [random.randrange(2000) for i in range(1000)] data = [(random.randrange(2000), i) for i in range(1000)]
f = lambda x: x * 547 % 2000 for f in (None, lambda x: x[0] * 547 % 2000):
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100): for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
self.assertEqual(nlargest(n, data), sorted(data, reverse=True)[:n]) self.assertEqual(nlargest(n, data), sorted(data, reverse=True)[:n])
self.assertEqual(nlargest(n, data, key=f), self.assertEqual(nlargest(n, data, key=f),
sorted(data, key=f, reverse=True)[:n]) sorted(data, key=f, reverse=True)[:n])
#============================================================================== #==============================================================================
......
...@@ -125,6 +125,8 @@ Extension Modules ...@@ -125,6 +125,8 @@ Extension Modules
Library Library
------- -------
- Fix sort stability in heapq.nlargest() and nsmallest().
- Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument. - Patch #1504073: Fix tarfile.open() for mode "r" with a fileobj argument.
- Patch #1262036: Prevent TarFiles from being added to themselves under - Patch #1262036: Prevent TarFiles from being added to themselves under
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment