pysnippets.lists.bifurcate_by
Split a list in two with a predicate
bifurcate_by(items: Iterable[T], predicate: Callable[[T], object]) -> tuple[list[T], list[T]]
Partition items into those that pass a test and those that don't, in one pass.
Two list comprehensions work, but they walk the data twice and call your test twice per item. That’s slow for an expensive check and wrong for a one-shot iterator.
bifurcate_by.py✓ ruff · mypy --strict
from collections.abc import Callable, Iterable
from typing import TypeVar
T = TypeVar("T")
def bifurcate_by(
items: Iterable[T], predicate: Callable[[T], object]
) -> tuple[list[T], list[T]]:
"""Split ``items`` into the ones that pass ``predicate`` and the ones that don't."""
passed: list[T] = []
failed: list[T] = []
for item in items:
(passed if predicate(item) else failed).append(item)
return passed, failed- one pass, so
predicateruns once per item
examples✓ 4 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> bifurcate_by(["beep", "boop", "foo", "bar"], lambda w: w.startswith("b"))(['beep', 'boop', 'bar'], ['foo'])passed on Python 3.11 to 3.14: >>> passed, failed = bifurcate_by(range(10), lambda n: n % 3 == 0)passed on Python 3.11 to 3.14: >>> passed, failed([0, 3, 6, 9], [1, 2, 4, 5, 7, 8])passed on Python 3.11 to 3.14: >>> bifurcate_by([], bool)([], [])Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).
python 3.14 · in your browser
Loading Python 3.14 in your browser (≈7 MB, cached after the first time)…
Tab inserts four spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the examples.
How it works
- One loop. The conditional expression picks which list to append to.
- Order is kept within each half.
- It returns a tuple, so
passed, failed = ...unpacks it.
Complexity: O(n) time, O(n) space
- 3.11✓passes
- 3.12✓passes
- 3.13✓passes
- 3.14✓passes
Import
from pysnippets.lists.bifurcate_by import bifurcate_byNo dependencies: copy bifurcate_by.py into your project, or clone the repo.Adapted from bifurcate-by in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Rewritten: single pass, returns a tuple, accepts any iterable, typed. Suggest an edit.