mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Add functools.CmpToKey()
This commit is contained in:
parent
fdaaa9c9d8
commit
a551f31d48
3 changed files with 73 additions and 0 deletions
|
@ -17,6 +17,28 @@ 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)
|
||||||
|
|
||||||
|
Transform an old-style comparison function to a key-function. Used with
|
||||||
|
tools that accept key functions (such as :func:`sorted`, :func:`min`,
|
||||||
|
:func:`max`, :func:`heapq.nlargest`, :func:`heapq.nsmallest`,
|
||||||
|
:func:`itertools.groupby`).
|
||||||
|
This function is primarily used as a transition tool for programs
|
||||||
|
being converted to Py3.x where comparison functions are no longer
|
||||||
|
supported.
|
||||||
|
|
||||||
|
A compare function is any callable that accept two arguments, compares
|
||||||
|
them, and returns a negative number for less-than, zero for equality,
|
||||||
|
or a positive number for greater-than. A key function is a callable
|
||||||
|
that accepts one argument and returns another value that indicates
|
||||||
|
the position in the desired collation sequence.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
sorted(iterable, key=CmpToKey(locale.strcoll)) # locale-aware sort order
|
||||||
|
|
||||||
|
.. versionadded:: 2.7
|
||||||
|
|
||||||
.. function:: total_ordering(cls)
|
.. function:: total_ordering(cls)
|
||||||
|
|
||||||
Given a class defining one or more rich comparison ordering methods, this
|
Given a class defining one or more rich comparison ordering methods, this
|
||||||
|
|
|
@ -49,3 +49,48 @@ def wraps(wrapped,
|
||||||
"""
|
"""
|
||||||
return partial(update_wrapper, wrapped=wrapped,
|
return partial(update_wrapper, wrapped=wrapped,
|
||||||
assigned=assigned, updated=updated)
|
assigned=assigned, updated=updated)
|
||||||
|
|
||||||
|
def total_ordering(cls):
|
||||||
|
'Class decorator that fills-in missing ordering methods'
|
||||||
|
convert = {
|
||||||
|
'__lt__': [('__gt__', lambda self, other: other < self),
|
||||||
|
('__le__', lambda self, other: not other < self),
|
||||||
|
('__ge__', lambda self, other: not self < other)],
|
||||||
|
'__le__': [('__ge__', lambda self, other: other <= self),
|
||||||
|
('__lt__', lambda self, other: not other <= self),
|
||||||
|
('__gt__', lambda self, other: not self <= other)],
|
||||||
|
'__gt__': [('__lt__', lambda self, other: other > self),
|
||||||
|
('__ge__', lambda self, other: not other > self),
|
||||||
|
('__le__', lambda self, other: not self > other)],
|
||||||
|
'__ge__': [('__le__', lambda self, other: other >= self),
|
||||||
|
('__gt__', lambda self, other: not other >= self),
|
||||||
|
('__lt__', lambda self, other: not self >= other)]
|
||||||
|
}
|
||||||
|
roots = set(dir(cls)) & set(convert)
|
||||||
|
assert roots, 'must define at least one ordering operation: < > <= >='
|
||||||
|
root = max(roots) # prefer __lt __ to __le__ to __gt__ to __ge__
|
||||||
|
for opname, opfunc in convert[root]:
|
||||||
|
if opname not in roots:
|
||||||
|
opfunc.__name__ = opname
|
||||||
|
opfunc.__doc__ = getattr(int, opname).__doc__
|
||||||
|
setattr(cls, opname, opfunc)
|
||||||
|
return cls
|
||||||
|
|
||||||
|
def CmpToKey(mycmp):
|
||||||
|
'Convert a cmp= function into a key= function'
|
||||||
|
class K(object):
|
||||||
|
def __init__(self, obj, *args):
|
||||||
|
self.obj = obj
|
||||||
|
def __lt__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) < 0
|
||||||
|
def __gt__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) > 0
|
||||||
|
def __eq__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) == 0
|
||||||
|
def __le__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) <= 0
|
||||||
|
def __ge__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) >= 0
|
||||||
|
def __ne__(self, other):
|
||||||
|
return mycmp(self.obj, other.obj) != 0
|
||||||
|
return K
|
||||||
|
|
|
@ -57,6 +57,12 @@ Library
|
||||||
|
|
||||||
- collections.Counter() now supports a subtract() method.
|
- collections.Counter() now supports a subtract() method.
|
||||||
|
|
||||||
|
- the functools module now has a total_ordering() class decorator
|
||||||
|
to simplify the specifying rich comparisons.
|
||||||
|
|
||||||
|
- The functools module also adds CmpToKey() as a tool to transition
|
||||||
|
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
|
||||||
instances directly.
|
instances directly.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue