Skip to main content

Custom ordering for sorting and data structures, using your own less-than (`<`) function.

Project description

less-than-key

Custom ordering for sorting and data structures, using your own less-than (<) function.

What is it?

less-than-key lets you define a "key function" for sorting using any custom less-than (<) function you like. It's useful anytime you want to sort or prioritize objects using arbitrary comparison logic, such as by descending order, absolute value, length, or anything else.

C++-Style Comparator Pattern, in Python

If you come from C++ (e.g., std::sort or std::priority_queue), you're used to passing a function (or functor) of the form bool operator()(const T& a, const T& b), which encodes your custom < logic. less-than-key explicitly brings the C++-style comparator pattern to Python:

def cpp_style_lt(a, b):
    return <your-strict-weak-ordering-here>

sorted(seq, key=less_than_to_key(cpp_style_lt))     # Just like std::sort(..., cmp)

Like C++, you can encapsulate arbitrary ordering logic, and use it seamlessly in sorting, heapq, etc. - with zero boilerplate.

Install

pip install less-than-key

Usage

# coding=utf-8
from less_than_key import less_than_to_key


# Sort numbers by their absolute value, in reverse order (largest abs first)
def abs_gt(a, b):
    return abs(a) > abs(b)


lst = [-3, 7, -1, 2]
assert sorted(lst, key=less_than_to_key(abs_gt)) == [7, -3, 2, -1]


# Sort strings by length, then alphabetically
def len_then_alpha(a, b):
    if len(a) != len(b):
        return len(a) < len(b)
    return a < b


words = ['pear', 'fig', 'apple', 'date']
assert sorted(words, key=less_than_to_key(len_then_alpha)) == ['fig', 'date', 'pear', 'apple']

# Use with `heapq` for custom priority
# Use max-heap semantics
import heapq
import operator

MaxHeapLessThanKey = less_than_to_key(operator.gt)

assert MaxHeapLessThanKey(1) > MaxHeapLessThanKey(2)
assert MaxHeapLessThanKey(1) >= MaxHeapLessThanKey(2)

assert MaxHeapLessThanKey(1) < MaxHeapLessThanKey(0)
assert MaxHeapLessThanKey(1) <= MaxHeapLessThanKey(0)

assert MaxHeapLessThanKey(1) == MaxHeapLessThanKey(1)
assert MaxHeapLessThanKey(1) >= MaxHeapLessThanKey(1)
assert MaxHeapLessThanKey(1) <= MaxHeapLessThanKey(1)

assert MaxHeapLessThanKey(1) != MaxHeapLessThanKey(2)

heap = [MaxHeapLessThanKey(x) for x in [5, 3, 7]]
heapq.heapify(heap)
assert heapq.heappop(heap).value == 7

API

less_than_to_key(less_than)

Returns a function suitable for sorting's key=... parameter, wrapping values in a class that uses your custom less-than function for all comparisons.

  • Parameters:
    • less_than: callable(a, b) -> bool
      Your less-than function (must provide a strict ordering, i.e., return True if a < b).
  • Returns:
    function - key function, e.g. key=less_than_to_key(my_lt)
  • Example:
    sorted(items, key=less_than_to_key(my_lt))

Advanced: LessThanKey

You can generate specialized classes if you want to use them directly or in custom data structures:

# coding=utf-8
from less_than_key import LessThanKey

AbsGreaterThanLessThanKey = LessThanKey[lambda a, b: abs(a) > abs(b)]
assert AbsGreaterThanLessThanKey(-10) < AbsGreaterThanLessThanKey(5)

Why not just use functools.cmp_to_key?

  • functools.cmp_to_key (in Python 3) is built for three-way comparison (-1, 0, 1) functions, but sometimes you want to provide only a strict less-than function.
  • This package is more direct and may be easier when you already have a "less-than" function, or want tight control ( e.g., when using with specialized containers).

Contributing

Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.

License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

less_than_key-0.1.0a0.tar.gz (5.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

less_than_key-0.1.0a0-py2.py3-none-any.whl (5.6 kB view details)

Uploaded Python 2Python 3

File details

Details for the file less_than_key-0.1.0a0.tar.gz.

File metadata

  • Download URL: less_than_key-0.1.0a0.tar.gz
  • Upload date:
  • Size: 5.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.2

File hashes

Hashes for less_than_key-0.1.0a0.tar.gz
Algorithm Hash digest
SHA256 e561c5726205a831fca98170036cce0a41e65556b287eba99ea1f95f31fbc785
MD5 6f8bb7e5cab1b31ba2bd247de54f35ad
BLAKE2b-256 f0bf82a851883c6d2c839df25862220363f2b0dcb33ed0be319b4119fe07ecc4

See more details on using hashes here.

File details

Details for the file less_than_key-0.1.0a0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for less_than_key-0.1.0a0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 48398a66c04fb881c60ebf225fe2a034ca2ccc47b60ddb6412b8743012daf18e
MD5 796e8ece1d2402f4907ce2c1da33b1c4
BLAKE2b-256 b003f306a013f6081bb827d106474ca073bd20bbe9c3322ee71b63512c0d6970

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page