[Python-Dev] adding key argument to min and max (original) (raw)

Raymond Hettinger python at rcn.com
Thu Dec 2 02:32:10 CET 2004


I don't want to put words into your mouth, so is this a vote against a key= argument for min and max?

Right. I don't think there is any need.

If nsmallest/nlargest get key= arguments, this would definitely cover the same cases.

Right.

If a key= argument gets vetoed for min and max, I'd at least like to add a bit of documentation pointing users of min/max to nsmallest/nlargest if they want a key= argument...

Sounds reasonable.

Raymond

P.S. In case you're interested, here is the patch:

Index: heapq.py

RCS file: /cvsroot/python/python/dist/src/Lib/heapq.py,v retrieving revision 1.27 diff -u -r1.27 heapq.py --- heapq.py 29 Nov 2004 05:54:47 -0000 1.27 +++ heapq.py 2 Dec 2004 01:32:44 -0000 @@ -307,6 +307,31 @@ except ImportError: pass +# Extend the implementations of nsmallest and nlargest to use a key= argument +_nsmallest = nsmallest +def nsmallest(n, iterable, key=None): + """Find the n smallest elements in a dataset. + + Equivalent to: sorted(iterable, key=key)[:n] + """ + if key is None: + return _nsmallest(n, iterable) + it = ((key(r), i, r) for i, r in enumerate(iterable)) # decorate + result = _nsmallest(n, it) + return [r for k, i, r in result] # undecorate + +_nlargest = nlargest +def nlargest(n, iterable, key=None): + """Find the n largest elements in a dataset. + + Equivalent to: sorted(iterable, key=key, reverse=True)[:n] + """ + if key is None: + return _nlargest(n, iterable) + it = ((key(r), i, r) for i, r in enumerate(iterable)) # decorate + result = _nlargest(n, it) + return [r for k, i, r in result] # undecorate + if name == "main": # Simple sanity test heap = [] Index: test/test_heapq.py

RCS file: /cvsroot/python/python/dist/src/Lib/test/test_heapq.py,v retrieving revision 1.16 diff -u -r1.16 test_heapq.py --- test/test_heapq.py 29 Nov 2004 05:54:48 -0000 1.16 +++ test/test_heapq.py 2 Dec 2004 01:32:44 -0000 @@ -105,13 +105,19 @@ def test_nsmallest(self): data = [random.randrange(2000) for i in range(1000)] + f = lambda x: x * 547 % 2000 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, key=f), + sorted(data, key=f)[:n]) def test_largest(self): data = [random.randrange(2000) for i in range(1000)] + f = lambda x: x * 547 % 2000 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, key=f), + sorted(data, key=f, reverse=True)[:n]) #=======================================================================



More information about the Python-Dev mailing list