Add tests for cmp_to_key.

Adopt PEP 8 compliant function name.
Factor-out existing uses cmp_to_key.
Update documentation to use internal pointers instead of external resource.
This commit is contained in:
Raymond Hettinger 2010-04-04 21:45:01 +00:00
parent 4f185228b0
commit bb006cf26c
8 changed files with 17 additions and 31 deletions

View File

@ -1154,9 +1154,8 @@ available. They are listed here in alphabetical order.
In general, the *key* and *reverse* conversion processes are much faster In general, the *key* and *reverse* conversion processes are much faster
than specifying an equivalent *cmp* function. This is because *cmp* is than specifying an equivalent *cmp* function. This is because *cmp* is
called multiple times for each list element while *key* and *reverse* touch called multiple times for each list element while *key* and *reverse* touch
each element only once. To convert an old-style *cmp* function to a *key* each element only once. Use :func:`functools.cmp_to_key` to convert an
function, see the `CmpToKey recipe in the ASPN cookbook old-style *cmp* function to a *key* function.
<http://code.activestate.com/recipes/576653/>`_\.
For sorting examples and a brief sorting tutorial, see `Sorting HowTo For sorting examples and a brief sorting tutorial, see `Sorting HowTo
<http://wiki.python.org/moin/HowTo/Sorting/>`_\. <http://wiki.python.org/moin/HowTo/Sorting/>`_\.

View File

@ -17,7 +17,7 @@ function for the purposes of this module.
The :mod:`functools` module defines the following functions: The :mod:`functools` module defines the following functions:
.. function:: CmpToKey(func) .. function:: cmp_to_key(func)
Transform an old-style comparison function to a key-function. Used with Transform an old-style comparison function to a key-function. Used with
tools that accept key functions (such as :func:`sorted`, :func:`min`, tools that accept key functions (such as :func:`sorted`, :func:`min`,
@ -35,7 +35,7 @@ The :mod:`functools` module defines the following functions:
Example:: Example::
sorted(iterable, key=CmpToKey(locale.strcoll)) # locale-aware sort order sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order
.. versionadded:: 2.7 .. versionadded:: 2.7

View File

@ -1618,7 +1618,8 @@ Notes:
In general, the *key* and *reverse* conversion processes are much faster than In general, the *key* and *reverse* conversion processes are much faster than
specifying an equivalent *cmp* function. This is because *cmp* is called specifying an equivalent *cmp* function. This is because *cmp* is called
multiple times for each list element while *key* and *reverse* touch each multiple times for each list element while *key* and *reverse* touch each
element only once. element only once. Use :func:`functools.cmp_to_key` to convert an
old-style *cmp* function to a *key* function.
.. versionchanged:: 2.3 .. versionchanged:: 2.3
Support for ``None`` as an equivalent to omitting *cmp* was added. Support for ``None`` as an equivalent to omitting *cmp* was added.

View File

@ -76,7 +76,7 @@ def total_ordering(cls):
setattr(cls, opname, opfunc) setattr(cls, opname, opfunc)
return cls return cls
def CmpToKey(mycmp): def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function' 'Convert a cmp= function into a key= function'
class K(object): class K(object):
def __init__(self, obj, *args): def __init__(self, obj, *args):

View File

@ -37,6 +37,7 @@ import os
import time import time
import marshal import marshal
import re import re
from functools import cmp_to_key
__all__ = ["Stats"] __all__ = ["Stats"]
@ -238,7 +239,7 @@ class Stats:
stats_list.append((cc, nc, tt, ct) + func + stats_list.append((cc, nc, tt, ct) + func +
(func_std_string(func), func)) (func_std_string(func), func))
stats_list.sort(key=CmpToKey(TupleComp(sort_tuple).compare)) stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare))
self.fcn_list = fcn_list = [] self.fcn_list = fcn_list = []
for tuple in stats_list: for tuple in stats_list:
@ -471,16 +472,6 @@ class TupleComp:
return direction return direction
return 0 return 0
def CmpToKey(mycmp):
"""Convert a cmp= function into a key= function"""
class K(object):
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) == -1
return K
#************************************************************************** #**************************************************************************
# func_name is a triple (file:string, line:int, name:string) # func_name is a triple (file:string, line:int, name:string)

View File

@ -338,7 +338,12 @@ class TestReduce(unittest.TestCase):
self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item self.assertEqual(reduce(42, "", "1"), "1") # func is never called with one item
self.assertRaises(TypeError, reduce, 42, (42, 42)) self.assertRaises(TypeError, reduce, 42, (42, 42))
class TestCmpToKey(unittest.TestCase):
def test_cmp_to_key(self):
def mycmp(x, y):
return y - x
self.assertEqual(sorted(range(5), key=functools.cmp_to_key(mycmp)),
[4, 3, 2, 1, 0])
def test_main(verbose=None): def test_main(verbose=None):

View File

@ -6,23 +6,13 @@ import sys
import traceback import traceback
import types import types
from functools import cmp_to_key as _CmpToKey
from fnmatch import fnmatch from fnmatch import fnmatch
from . import case, suite from . import case, suite
__unittest = True __unittest = True
def _CmpToKey(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) == -1
return K
# what about .pyc or .pyo (etc) # what about .pyc or .pyo (etc)
# we would need to avoid loading the same tests multiple times # we would need to avoid loading the same tests multiple times
# from '.py', '.pyc' *and* '.pyo' # from '.py', '.pyc' *and* '.pyo'

View File

@ -60,7 +60,7 @@ Library
- the functools module now has a total_ordering() class decorator - the functools module now has a total_ordering() class decorator
to simplify the specifying rich comparisons. to simplify the specifying rich comparisons.
- The functools module also adds CmpToKey() as a tool to transition - The functools module also adds cmp_to_key() as a tool to transition
old-style comparison functions to new-style key-functions. old-style comparison functions to new-style key-functions.
- Issue #8294: The Fraction constructor now accepts Decimal and float - Issue #8294: The Fraction constructor now accepts Decimal and float