Kaydet (Commit) e22072fb authored tarafından Alexander Marshalov's avatar Alexander Marshalov Kaydeden (comit) Raymond Hettinger

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().
üst bde782bb
...@@ -869,6 +869,9 @@ are always available. They are listed here in alphabetical order. ...@@ -869,6 +869,9 @@ are always available. They are listed here in alphabetical order.
.. versionadded:: 3.4 .. versionadded:: 3.4
The *default* keyword-only argument. The *default* keyword-only argument.
.. versionchanged:: 3.8
The *key* can be ``None``.
.. _func-memoryview: .. _func-memoryview:
.. function:: memoryview(obj) .. function:: memoryview(obj)
...@@ -903,6 +906,9 @@ are always available. They are listed here in alphabetical order. ...@@ -903,6 +906,9 @@ are always available. They are listed here in alphabetical order.
.. versionadded:: 3.4 .. versionadded:: 3.4
The *default* keyword-only argument. The *default* keyword-only argument.
.. versionchanged:: 3.8
The *key* can be ``None``.
.. function:: next(iterator[, default]) .. function:: next(iterator[, default])
......
...@@ -468,10 +468,7 @@ def nsmallest(n, iterable, key=None): ...@@ -468,10 +468,7 @@ def nsmallest(n, iterable, key=None):
if n == 1: if n == 1:
it = iter(iterable) it = iter(iterable)
sentinel = object() sentinel = object()
if key is None: result = min(it, default=sentinel, key=key)
result = min(it, default=sentinel)
else:
result = min(it, default=sentinel, key=key)
return [] if result is sentinel else [result] return [] if result is sentinel else [result]
# When n>=size, it's faster to use sorted() # When n>=size, it's faster to use sorted()
...@@ -531,10 +528,7 @@ def nlargest(n, iterable, key=None): ...@@ -531,10 +528,7 @@ def nlargest(n, iterable, key=None):
if n == 1: if n == 1:
it = iter(iterable) it = iter(iterable)
sentinel = object() sentinel = object()
if key is None: result = max(it, default=sentinel, key=key)
result = max(it, default=sentinel)
else:
result = max(it, default=sentinel, key=key)
return [] if result is sentinel else [result] return [] if result is sentinel else [result]
# When n>=size, it's faster to use sorted() # When n>=size, it's faster to use sorted()
......
...@@ -905,6 +905,8 @@ class BuiltinTest(unittest.TestCase): ...@@ -905,6 +905,8 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(max((), default=1, key=neg), 1) self.assertEqual(max((), default=1, key=neg), 1)
self.assertEqual(max((1, 2), default=3, key=neg), 1) self.assertEqual(max((1, 2), default=3, key=neg), 1)
self.assertEqual(max((1, 2), key=None), 2)
data = [random.randrange(200) for i in range(100)] data = [random.randrange(200) for i in range(100)]
keys = dict((elem, random.randrange(50)) for elem in data) keys = dict((elem, random.randrange(50)) for elem in data)
f = keys.__getitem__ f = keys.__getitem__
...@@ -957,6 +959,8 @@ class BuiltinTest(unittest.TestCase): ...@@ -957,6 +959,8 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(min((), default=1, key=neg), 1) self.assertEqual(min((), default=1, key=neg), 1)
self.assertEqual(min((1, 2), default=1, key=neg), 2) self.assertEqual(min((1, 2), default=1, key=neg), 2)
self.assertEqual(min((1, 2), key=None), 1)
data = [random.randrange(200) for i in range(100)] data = [random.randrange(200) for i in range(100)]
keys = dict((elem, random.randrange(50)) for elem in data) keys = dict((elem, random.randrange(50)) for elem in data)
f = keys.__getitem__ f = keys.__getitem__
......
Fix min and max functions to get default behavior when key is None.
...@@ -1639,6 +1639,10 @@ min_max(PyObject *args, PyObject *kwds, int op) ...@@ -1639,6 +1639,10 @@ min_max(PyObject *args, PyObject *kwds, int op)
return NULL; return NULL;
} }
if (keyfunc == Py_None) {
keyfunc = NULL;
}
maxitem = NULL; /* the result */ maxitem = NULL; /* the result */
maxval = NULL; /* the value associated with the result */ maxval = NULL; /* the value associated with the result */
while (( item = PyIter_Next(it) )) { while (( item = PyIter_Next(it) )) {
......
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