Simple LINQ in Python
Project description
spinq
LINQ-style collection helpers for Python. Provides familiar operations (first, where, select, order_by, etc.) as plain functions for lists and dicts, with a trailing _ convention to avoid shadowing Python builtins.
Requirements
Python 3.14+
Installation
pip install spinq
Lists
from spinq.lists import (
first_, first_or_none_, first_or_none_with_index_,
last_, last_or_none_,
single_, single_or_none_,
filter_, where_, where_with_index_,
except_, without_,
select_, select_many_,
union_, distinct_,
order_by_, order_by_descending_,
any_, all_, none_,
)
Lookup
| Function | Description |
|---|---|
first_(seq, predicate?) |
First matching element; raises ValueError if none. |
first_or_none_(seq, predicate?) |
First matching element or None. |
first_or_none_with_index_(seq, predicate?) |
First match as (index, item) or None. |
last_(seq, predicate?) |
Last matching element; raises ValueError if none. |
last_or_none_(seq, predicate?) |
Last matching element or None. |
single_(seq, predicate) |
Exactly one match; raises if zero or more than one. |
single_or_none_(seq, predicate) |
One match or None; raises if more than one. |
Filtering
| Function | Description |
|---|---|
filter_(seq, predicate) |
Elements that satisfy the predicate. |
where_(seq, predicate) |
Alias for filter_. |
where_with_index_(seq, predicate) |
Matching elements as {index: item} dict. |
except_(seq, exclusions) |
Elements not present in exclusions. |
without_(seq, predicate) |
Elements that do not satisfy the predicate. |
distinct_(seq) |
Deduplicated elements (order not guaranteed). |
Projection
| Function | Description |
|---|---|
select_(seq, selector) |
Map each element. |
select_many_(seq, selector) |
Flat-map each element (selector returns a list). |
Set operations
| Function | Description |
|---|---|
union_(seq1, seq2) |
Distinct union of two lists. |
Sorting
| Function | Description |
|---|---|
order_by_(seq, key_selector) |
Ascending sort. |
order_by_descending_(seq, key_selector) |
Descending sort. |
Quantifiers
| Function | Description |
|---|---|
any_(seq, predicate) |
True if any element satisfies the predicate. |
all_(seq, predicate) |
True if all elements satisfy the predicate. |
none_(seq, predicate) |
True if no element satisfies the predicate. |
Examples
from spinq.lists import where_, select_, first_, order_by_
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
evens = where_(numbers, lambda x: x % 2 == 0) # [4, 2, 6]
doubled = select_(evens, lambda x: x * 2) # [8, 4, 12]
smallest_even = first_(numbers, lambda x: x % 2 == 0) # 4
sorted_nums = order_by_(numbers, lambda x: x) # [1, 1, 2, 3, 4, 5, 6, 9]
Dicts
from spinq.dicts import first_, first_or_none_, get_key_by_index_, get_key_value_by_index_
| Function | Description |
|---|---|
first_(d, predicate?) |
First (key, value) tuple whose value satisfies the predicate; raises if none. |
first_or_none_(d, predicate?) |
Same, returns None if not found. |
get_key_by_index_(d, index) |
Key at insertion-order index. |
get_key_value_by_index_(d, index) |
(key, value) at insertion-order index. |
Example
from spinq.dicts import first_or_none_, get_key_value_by_index_
scores = {"alice": 95, "bob": 72, "carol": 88}
top = first_or_none_(scores, lambda v: v >= 90) # ("alice", 95)
second = get_key_value_by_index_(scores, 1) # ("bob", 72)
License
MIT
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
spinq-1.5.0.tar.gz
(6.9 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
spinq-1.5.0-py3-none-any.whl
(4.7 kB
view details)
File details
Details for the file spinq-1.5.0.tar.gz.
File metadata
- Download URL: spinq-1.5.0.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25c57f4e8b8ce1444dd32c3e1269a4f42ae7430878838066f49e70166af62315
|
|
| MD5 |
894ec1dbf890feb51439630dcb6aa0d7
|
|
| BLAKE2b-256 |
35d54898900434ada134ab3b16c2116777d499dd6039aef799c0db5e51691107
|
File details
Details for the file spinq-1.5.0-py3-none-any.whl.
File metadata
- Download URL: spinq-1.5.0-py3-none-any.whl
- Upload date:
- Size: 4.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a76cfd4d3b322afb08f373d80dde9b8f7ba768c6779a98ee745c3f9a6812c929
|
|
| MD5 |
c115ba37f587f4be97244ab8219de16c
|
|
| BLAKE2b-256 |
de7c4a8cbcfcab78234804fc49040b327d4bea36aa94400b331940d19b2f8d6c
|