This project has been archived by its maintainers, and is no longer receiving any updates.
GitHub | PyPI | Issues | Changelog
Do you have a list of integers? Do you want to know what ranges of consecutive values the list covers? Do you need to solve a gaps and islands problem outside of SQL? Maybe you have a list of dates and need to find the longest streak of consecutive days on which something happened. No? Why not? Well, either way, the derange module is here for you, ready to solve all these problems and a couple more.
Installation
derange requires Python 3.8 or higher. Just use pip for Python 3 (You have pip, right?) to install it:
python3 -m pip install derange
Examples
Condense commit years obtained from git log or the like into range objects:
>>> import derange >>> derange.derange([2015, 2015, 2015, 2014, 2014, 2011, 2010, 2010, 2009, 2009]) [range(2009, 2012), range(2014, 2016)]
If the input is already sorted, you can condense it slightly faster with derange_sorted():
>>> derange.derange_sorted([2009, 2009, 2010, 2010, 2011, 2014, 2014, 2015, 2015, 2015]) [range(2009, 2012), range(2014, 2016)]
Organize non-integer values into closed intervals (represented as pairs of endpoints) with deinterval():
>>> import datetime >>> # deinterval() requires a callable for determining when two values are "adjacent": >>> def within_24_hours(a,b): ... return abs(a-b) <= datetime.timedelta(hours=24) ... >>> timestamps = [ ... datetime.datetime(2017, 11, 2, 12, 0), ... datetime.datetime(2017, 11, 3, 11, 0), ... datetime.datetime(2017, 11, 4, 10, 0), ... datetime.datetime(2017, 11, 5, 9, 0), ... datetime.datetime(2017, 11, 6, 9, 0), ... datetime.datetime(2017, 11, 7, 10, 0), ... ] >>> derange.deinterval(within_24_hours, timestamps) [(datetime.datetime(2017, 11, 2, 12, 0), datetime.datetime(2017, 11, 6, 9, 0)), (datetime.datetime(2017, 11, 7, 10, 0), datetime.datetime(2017, 11, 7, 10, 0))]
… which also has a deinterval_sorted() variant:
>>> derange.deinterval_sorted(within_24_hours, timestamps)
[(datetime.datetime(2017, 11, 2, 12, 0), datetime.datetime(2017, 11, 6, 9, 0)), (datetime.datetime(2017, 11, 7, 10, 0), datetime.datetime(2017, 11, 7, 10, 0))]
>>> derange.deinterval_sorted(within_24_hours, reversed(timestamps))
Traceback (most recent call last):
...
ValueError: sequence not in ascending order
API
derange.derange(iterable: Iterable[int]) -> List[range]
Convert a sequence of integers to a minimal list of range objects that together contain all of the input elements.
Output is in strictly ascending order. Input need not be in order (but see also derange_sorted()). Duplicate input values are ignored.
derange.derange_sorted(iterable: Iterable[int]) -> List[range]
Convert a non-decreasing sequence of integers to a minimal list of range objects that together contain all of the input elements. This is faster than derange() but only accepts sorted input.
derange.deinterval(
adjacent: Callable[[T,T], bool],
iterable: Iterable[T],
) -> List[Tuple[T,T]]
Convert a sequence of totally-ordered values to a minimal list of closed intervals (represented as pairs of endpoints) that together contain all of the input elements. This is a generalization of derange() for arbitrary types.
Two input values will be placed in the same interval iff they are directly adjacent or there exists a chain of adjacent input values connecting them, where adjacency is defined by the given adjacent callable.
adjacent will be called with two elements of iterable at a time to test whether they should be placed in the same interval. The binary relation implied by adjacent must be reflexive and symmetric, and for all x < y < z, if adjacent(x, z) is true, then both adjacent(x, y) and adjacent(y, z) must also be true.
Output is in strictly ascending order. Input need not be in order (but see also deinterval_sorted()). Duplicate input values are ignored.
Note that, unlike with range objects, intervals returned from deinterval() contain their upper bounds.
derange.deinterval_sorted(
adjacent: Callable[[T,T], bool],
iterable: Iterable[T],
) -> List[Tuple[T,T]]
Convert a non-decreasing sequence of totally-ordered values to a minimal list of closed intervals that together contain all of the input elements. This is faster than deinterval() but only accepts sorted input.
Metadata
Release files for derange 0.2.2.post1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| derange-0.2.2.post1.tar.gz | 7.9 kB | Without provenance | Details for derange-0.2.2.post1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| derange-0.2.2.post1-py3-none-any.whl | Python 3 | none | any | Details for derange-0.2.2.post1-py3-none-any.whl |
Total release size: 14.5 kB
Release files / derange-0.2.2.post1.tar.gz
| Download URL | derange-0.2.2.post1.tar.gz |
|---|---|
| Size | 7.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
56a4b9b9acee81b813b8b1668c8c85c58e4c59f9e9f628f21cf23ba63837ca37
|
|
BLAKE2b-256 checksum How to use checksums |
fd8af5f3570a7f7bd7550086aa058a07d77c128e0f0bceea53a786468c30db3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / derange-0.2.2.post1-py3-none-any.whl
| Download URL | derange-0.2.2.post1-py3-none-any.whl |
|---|---|
| Size | 6.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9c9c2b7797a1adb2a7689fc53e03dcb87e41d1386327a4a9ec8541fd5f3def69
|
|
BLAKE2b-256 checksum How to use checksums |
cdeda5f402ed568ecc638649dc928466e193528e4e68c7c268381432d1697a66
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for derange 0.2.2.post1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.