Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4901a1f

Browse files
committed
Add key= argument to heapq.nsmallest() and heapq.nlargest().
1 parent de7b990 commit 4901a1f

4 files changed

Lines changed: 90 additions & 8 deletions

File tree

Doc/lib/libheapq.tex

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,24 @@ \section{\module{heapq} ---
9090

9191
The module also offers two general purpose functions based on heaps.
9292

93-
\begin{funcdesc}{nlargest}{n, iterable}
93+
\begin{funcdesc}{nlargest}{n, iterable\optional{, key}}
9494
Return a list with the \var{n} largest elements from the dataset defined
95-
by \var{iterable}. Equivalent to: \code{sorted(iterable, reverse=True)[:n]}
96-
\versionadded{2.4}
95+
by \var{iterable}. \var{key}, if provided, specifies a function of one
96+
argument that is used to extract a comparison key from each element
97+
in the iterable: \samp{\var{key}=\function{str.lower}}
98+
Equivalent to: \samp{sorted(iterable, key=key, reverse=True)[:n]}
99+
\versionadded{2.4}
100+
\versionchanged[Added the optional \var{key} argument]{2.5}
97101
\end{funcdesc}
98102

99-
\begin{funcdesc}{nsmallest}{n, iterable}
103+
\begin{funcdesc}{nsmallest}{n, iterable\optional{, key}}
100104
Return a list with the \var{n} smallest elements from the dataset defined
101-
by \var{iterable}. Equivalent to: \code{sorted(iterable)[:n]}
102-
\versionadded{2.4}
105+
by \var{iterable}. \var{key}, if provided, specifies a function of one
106+
argument that is used to extract a comparison key from each element
107+
in the iterable: \samp{\var{key}=\function{str.lower}}
108+
Equivalent to: \samp{sorted(iterable, key=key)[:n]}
109+
\versionadded{2.4}
110+
\versionchanged[Added the optional \var{key} argument]{2.5}
103111
\end{funcdesc}
104112

105113
Both functions perform best for smaller values of \var{n}. For larger

Lib/heapq.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@
129129
__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'nlargest',
130130
'nsmallest']
131131

132-
from itertools import islice, repeat
132+
from itertools import islice, repeat, count, imap, izip, tee
133+
from operator import itemgetter
133134
import bisect
134135

135136
def heappush(heap, item):
@@ -307,6 +308,33 @@ def _siftup(heap, pos):
307308
except ImportError:
308309
pass
309310

311+
# Extend the implementations of nsmallest and nlargest to use a key= argument
312+
_nsmallest = nsmallest
313+
def nsmallest(n, iterable, key=None):
314+
"""Find the n smallest elements in a dataset.
315+
316+
Equivalent to: sorted(iterable, key=key)[:n]
317+
"""
318+
if key is None:
319+
return _nsmallest(n, iterable)
320+
in1, in2 = tee(iterable)
321+
it = izip(imap(key, in1), count(), in2) # decorate
322+
result = _nsmallest(n, it)
323+
return map(itemgetter(2), result) # undecorate
324+
325+
_nlargest = nlargest
326+
def nlargest(n, iterable, key=None):
327+
"""Find the n largest elements in a dataset.
328+
329+
Equivalent to: sorted(iterable, key=key, reverse=True)[:n]
330+
"""
331+
if key is None:
332+
return _nlargest(n, iterable)
333+
in1, in2 = tee(iterable)
334+
it = izip(imap(key, in1), count(), in2) # decorate
335+
result = _nlargest(n, it)
336+
return map(itemgetter(2), result) # undecorate
337+
310338
if __name__ == "__main__":
311339
# Simple sanity test
312340
heap = []

Lib/test/test_heapq.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,19 @@ def test_heapsort(self):
105105

106106
def test_nsmallest(self):
107107
data = [random.randrange(2000) for i in range(1000)]
108+
f = lambda x: x * 547 % 2000
108109
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
109110
self.assertEqual(nsmallest(n, data), sorted(data)[:n])
111+
self.assertEqual(nsmallest(n, data, key=f),
112+
sorted(data, key=f)[:n])
110113

111-
def test_largest(self):
114+
def test_nlargest(self):
112115
data = [random.randrange(2000) for i in range(1000)]
116+
f = lambda x: x * 547 % 2000
113117
for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100):
114118
self.assertEqual(nlargest(n, data), sorted(data, reverse=True)[:n])
119+
self.assertEqual(nlargest(n, data, key=f),
120+
sorted(data, key=f, reverse=True)[:n])
115121

116122

117123
#==============================================================================

Misc/NEWS

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,46 @@ Python News
44

55
(editors: check NEWS.help for information about editing NEWS using ReST.)
66

7+
What's New in Python 2.5 alpha 1?
8+
=================================
9+
10+
Core and builtins
11+
-----------------
12+
13+
14+
Extension Modules
15+
-----------------
16+
17+
18+
Library
19+
-------
20+
21+
- heapq.nsmallest() and heapq.nlargest() now support key= arguments with
22+
the same meaning as for list.sort().
23+
24+
25+
Build
26+
-----
27+
28+
29+
C API
30+
-----
31+
32+
33+
Tests
34+
-----
35+
36+
37+
Mac
38+
---
39+
40+
41+
42+
Tools/Demos
43+
-----------
44+
45+
46+
747
What's New in Python 2.4 final?
848
===============================
949

0 commit comments

Comments
 (0)