Skip to content

Commit e22072f

Browse files
Amperrhettinger
authored andcommitted
bpo-34149: Behavior of the min/max with key=None (GH-8328)
Improve consistency with the signature for sorted(), heapq.nsmallest(), heapq.nlargest(), and itertools.groupby().
1 parent bde782b commit e22072f

File tree

5 files changed

+17
-8
lines changed

5 files changed

+17
-8
lines changed

Doc/library/functions.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,9 @@ are always available. They are listed here in alphabetical order.
869869
.. versionadded:: 3.4
870870
The *default* keyword-only argument.
871871

872+
.. versionchanged:: 3.8
873+
The *key* can be ``None``.
874+
872875

873876
.. _func-memoryview:
874877
.. function:: memoryview(obj)
@@ -903,6 +906,9 @@ are always available. They are listed here in alphabetical order.
903906
.. versionadded:: 3.4
904907
The *default* keyword-only argument.
905908

909+
.. versionchanged:: 3.8
910+
The *key* can be ``None``.
911+
906912

907913
.. function:: next(iterator[, default])
908914

Lib/heapq.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,7 @@ def nsmallest(n, iterable, key=None):
468468
if n == 1:
469469
it = iter(iterable)
470470
sentinel = object()
471-
if key is None:
472-
result = min(it, default=sentinel)
473-
else:
474-
result = min(it, default=sentinel, key=key)
471+
result = min(it, default=sentinel, key=key)
475472
return [] if result is sentinel else [result]
476473

477474
# When n>=size, it's faster to use sorted()
@@ -531,10 +528,7 @@ def nlargest(n, iterable, key=None):
531528
if n == 1:
532529
it = iter(iterable)
533530
sentinel = object()
534-
if key is None:
535-
result = max(it, default=sentinel)
536-
else:
537-
result = max(it, default=sentinel, key=key)
531+
result = max(it, default=sentinel, key=key)
538532
return [] if result is sentinel else [result]
539533

540534
# When n>=size, it's faster to use sorted()

Lib/test/test_builtin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ def __getitem__(self, index):
905905
self.assertEqual(max((), default=1, key=neg), 1)
906906
self.assertEqual(max((1, 2), default=3, key=neg), 1)
907907

908+
self.assertEqual(max((1, 2), key=None), 2)
909+
908910
data = [random.randrange(200) for i in range(100)]
909911
keys = dict((elem, random.randrange(50)) for elem in data)
910912
f = keys.__getitem__
@@ -957,6 +959,8 @@ def __getitem__(self, index):
957959
self.assertEqual(min((), default=1, key=neg), 1)
958960
self.assertEqual(min((1, 2), default=1, key=neg), 2)
959961

962+
self.assertEqual(min((1, 2), key=None), 1)
963+
960964
data = [random.randrange(200) for i in range(100)]
961965
keys = dict((elem, random.randrange(50)) for elem in data)
962966
f = keys.__getitem__
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix min and max functions to get default behavior when key is None.

Python/bltinmodule.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,10 @@ min_max(PyObject *args, PyObject *kwds, int op)
16391639
return NULL;
16401640
}
16411641

1642+
if (keyfunc == Py_None) {
1643+
keyfunc = NULL;
1644+
}
1645+
16421646
maxitem = NULL; /* the result */
16431647
maxval = NULL; /* the value associated with the result */
16441648
while (( item = PyIter_Next(it) )) {

0 commit comments

Comments
 (0)