Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

FlpIt

Fluent LINQ for Python — LINQ semantics, Python-native execution

FlpIt brings a strongly typed, LINQ-style API to standard Python iterables. It combines the fluent query model and semantics of .NET LINQ with Python's native iterable and generator model.

Semantic goal: flp strives to faithfully reproduce .NET LINQ semantics.
Where Python's language or type system requires a different API contract, the contract is adapted accordingly. The implementation is actively developed, and semantic deviations may still exist.

⚡ Key Features

  • ⚡ Lazy Evaluation (FlpIt): Deferred, streaming execution where the underlying operation permits it. FlpIt wraps a standard Python Iterable[T].
  • 📦 Materialized Container (FlpList): Eager, mutable container backed by collections.UserList.
  • 🎯 LINQ Semantics: Operators such as .any(), .first(), .single(), .order_by(), and .then_by() follow .NET LINQ semantics.
  • 🔀 Independent Query Pipelines: Derived queries are independent and never mutate or retroactively affect separately created queries.
  • 🧠 Lazy Internal Materialization: Some operators, such as ordering, require internal materialization during deferred execution, while the query itself remains lazy.
  • 🔹 Static-First Typing: Designed for precise pyrefly inference without plugins (mypy and pyright might give varying results).
  • 🐍 Python-Native: Built on standard Python iterables, iterators, generators, and callable semantics.

🤸 Flipping the Pipeline

Native Python functional operations tend to produce an inside-out, right-to-left reading pattern...

# 🔁 Native Built-ins
result = list(map(lambda x: x * 10, filter(lambda x: x % 2 == 0, range(1, 11))))

# 🤸 FlpIt Pipeline
result = (
    flp.it(range(1, 11))
    .where(lambda x: x % 2 == 0)
    .select(lambda x: x * 10)
    .to_list()
)

💡 Quick Start

from flpit import flp, FlpIt, FlpList

# Deferred iterable via shorthand
data: FlpIt[int] = flp.it(range(1, 11))

# Lazy, streaming pipeline
query: FlpIt[int] = (
    data
    .where(lambda x: x % 2 == 0)
    .select(lambda x: x * 10)
)

# Explicit materialization
result: FlpList[int] = query.to_list()
# [20, 40, 60, 80, 100]

# Or start directly with an eager container
eager_list: FlpList[int] = flp.lst([1, 2, 3, 4])

🔬 LINQ Semantics, Python Runtime

flpit deliberately separates the two:

  • LINQ defines the query semantics.
  • Python provides the underlying iterable and execution model.

For example:

query.any()
query.first()
query.single()

use LINQ semantics, while native Python operations remain Pythonic:

any(query)
list(query)

This provides a predictable LINQ vocabulary without attempting to replace Python's native iteration model.

🔗 Independent Queries

LINQ queries are composable without mutating the query they were derived from.

For example:

@dataclass
class Item: group: str; value: int

original = flp.it([Item("A", 2), Item("B", 1)])

ordered = original.order_by(lambda x: x.group)

extended = original.concat([Item("A", 1), Item("B", 2)])

ordered_by_group_and_value = ordered.then_by(lambda x: x.value)

The resulting query graph is:

original
   │
   ├── order_by ──→ ordered
   │                  │
   │                  └── then_by ──→ ordered_by_group_and_value
   │
   └── concat ─────→ extended

ordered_by_group_and_value is derived from ordered.
It does not modify original, and it is not affected by the separately created extended query.

This matches the independent-query behavior of .NET LINQ.

🧠 Lazy Pipelines

Streaming operations do not materialize intermediate results:

query = (
    flp.it(source)
    .where(predicate)
    .select(selector)
    .order_by(key_selector)
    .take(100)
)

Conceptually:

source
  │
  ▼
where       ← streaming
  │
  ▼
select      ← streaming
  │
  ▼
order_by    ← lazy, internally buffers when enumerated
  │
  ▼
take        ← streaming
  │
  ▼
to_list     ← consumer-facing materialization

Operations such as order_by() necessarily materialize their input internally to establish ordering.

⚙️ Installation

uv add flpit

📜 License

Distributed under the MIT License. See LICENSE for more information.

Release files for flpit 0.1.4.dev5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flpit 0.1.4.dev5
File Size Uploaded
flpit-0.1.4.dev5.tar.gz 10.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flpit 0.1.4.dev5
File Interpreter ABI Platform
flpit-0.1.4.dev5-py3-none-any.whl Python 3 none any Details

Total release size: 22.4 kB

Release files / flpit-0.1.4.dev5.tar.gz

Download URL flpit-0.1.4.dev5.tar.gz
Size 10.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f6ee49d8ed7797f7253e770487a04868a1106aa6ac23bd727ceb4e84b8c4e6a0
BLAKE2b-256 checksum
How to use checksums
b8546dc4298d4acca50e449e8a4b97cff2104d600812f1ec167bec6d4e024aef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / flpit-0.1.4.dev5-py3-none-any.whl

Download URL flpit-0.1.4.dev5-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdff76270c653cf383baee03cfafda9c500c599743e34cb55c1f8c36ddac0c4e
BLAKE2b-256 checksum
How to use checksums
45cb0b95965aead1945ceb279ae16824dc55eb705169e4ee1489d647bf55816b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page