Standard predicates
This section describes the predicates that are included in py-predicate.
Set predicates
A collection of predicates that act on sets.
in_p
Return True if the values are included in the container, otherwise False.
from predicate import in_p
in_123 = in_p([1, 2, 3])
assert not in_123(0)
assert in_123(1)
intersects_p
Return True if the value shares at least one element with the given set, otherwise False.
from predicate import intersects_p
intersects_123 = intersects_p({1, 2, 3})
assert not intersects_123([4, 5, 6])
assert intersects_123([2, 4, 6])
is_subset_p
Return True if the value is a subset, otherwise False.
from predicate import is_subset_p
sub_123 = is_subset_p({1, 2, 3})
assert not sub_123({0, 1})
assert sub_123({1, 2})
is_superset_p
Return True if the value is a superset, otherwise False.
from predicate import is_superset_p
super_123 = is_superset_p({1, 2, 3})
assert not super_123({1, 2, 4})
assert super_123({1, 2, 3, 4})
is_real_subset_p
Return True if the value is a real subset, otherwise False.
from predicate import is_real_subset_p
sub_123 = is_real_subset_p({1, 2, 3})
assert not sub_123({1, 2, 3})
assert sub_123({1, 2})
is_real_superset_p
Return True if the value is a real superset, otherwise False.
from predicate import is_real_superset_p
super_123 = is_real_superset_p({1, 2, 3})
assert not super_123({1, 2, 3})
assert super_123({1, 2, 3, 4})
not_in_p
Return True if the values are not in the container, otherwise False.
from predicate import not_in_p
not_in_123 = not_in_p([1, 2, 3])
assert not_in_123(0)
assert not not_in_123(1)
String predicates
A collection of predicates that act on strings.
ends_with_p
Return True if the string ends with the given suffix, otherwise False.
from predicate import ends_with_p
ends_with_ing = ends_with_p("ing")
assert ends_with_ing("running")
assert not ends_with_ing("run")
is_alnum_p
Return True if all characters in the string are alphanumeric and there is at least one character, False otherwise.
from predicate import is_alnum_p
assert is_alnum_p("abc123")
assert not is_alnum_p("abc 123")
assert not is_alnum_p("")
is_alpha_p
Return True if all characters in the string are alphabetic and there is at least one character, False otherwise.
from predicate import is_alpha_p
assert is_alpha_p("abc")
assert not is_alpha_p("abc123")
is_ascii_p
Return True if the string is empty or all characters in the string are ASCII, False otherwise.
from predicate import is_ascii_p
assert is_ascii_p("hello")
assert is_ascii_p("")
assert not is_ascii_p("héllo")
is_decimal_p
Return True if all characters in the string are decimal characters and there is at least one character, False otherwise.
from predicate import is_decimal_p
assert is_decimal_p("123")
assert not is_decimal_p("12.3")
assert not is_decimal_p("")
is_digit_p
Return True if all characters in the string are digits and there is at least one character, False otherwise.
from predicate import is_digit_p
assert is_digit_p("123")
assert not is_digit_p("12.3")
is_identifier_p
Return True if the string is a valid Python identifier, False otherwise.
from predicate import is_identifier_p
assert is_identifier_p("my_var")
assert is_identifier_p("_private")
assert not is_identifier_p("123abc")
assert not is_identifier_p("my-var")
is_lower_p
Return True if all cased characters in the string are lowercase and there is at least one cased character, False otherwise.
from predicate import is_lower_p
assert is_lower_p("hello")
assert not is_lower_p("Hello")
is_numeric_p
Return True if all characters in the string are numeric characters and there is at least one character, False otherwise.
from predicate import is_numeric_p
assert is_numeric_p("123")
assert not is_numeric_p("12.3")
is_printable_p
Return True if all characters in the string are printable or the string is empty, False otherwise.
from predicate import is_printable_p
assert is_printable_p("hello")
assert is_printable_p("")
assert not is_printable_p("hello\x00")
is_space_p
Return True if there are only whitespace characters in the string and there is at least one character, False otherwise.
from predicate import is_space_p
assert is_space_p(" ")
assert is_space_p("\t\n")
assert not is_space_p("")
assert not is_space_p("hello")
is_title_p
Return True if the string is titlecased (each word starts with an uppercase letter) and there is at least one character, False otherwise.
from predicate import is_title_p
assert is_title_p("Hello World")
assert not is_title_p("hello world")
assert not is_title_p("HELLO WORLD")
is_upper_p
Return True if all cased characters in the string are uppercase and there is at least one cased character, False otherwise.
from predicate import is_upper_p
assert is_upper_p("HELLO")
assert not is_upper_p("Hello")
starts_with_p
Return True if the string starts with the given prefix, otherwise False.
from predicate import starts_with_p
starts_with_py = starts_with_p("py")
assert starts_with_py("python")
assert not starts_with_py("java")
all_p
This predicate tests if for all elements in an Iterable, the enclosed predicate is True:
from predicate import all_p, is_int_p
# Predicate to test if all items in an iterable are of type int
all_int = all_p(is_int_p)
assert all_int([1, 2, 3])
assert not all_int([None, 2, 3])
The equivalent code without using predicates could be something like:
def all_int(iter: Iterable) -> bool:
return all(isinstance(ele, int) for ele in iter)
always_false_p
This predicate ignores any arguments and always returns False:
from predicate import always_false_p
assert not always_false_p(13)
This might be the result of an optimization.
always_p
Synonym for always_true_p.
always_true_p
This predicate ignores any arguments and always returns True:
from predicate import always_true_p
assert always_true_p(13)
This might be the result of an optimization.
any_p
This predicate tests if for any element in an Iterable, the enclosed predicate is True:
from predicate import any_p, is_int_p
# Predicate to test if any of the items in an iterable is of type int
any_int = any_p(is_int_p)
assert not any_int(())
assert any_int((1, 2, 3))
assert any_int([1, 2, 3])
assert any_int([None, 2, 3])
comp_p
This predicate transforms the input with a function and then tests the result against a predicate.
from predicate import comp_p, ge_p
# True if the length of the list is >= 3
long_enough = comp_p(len, ge_p(3))
assert long_enough([1, 2, 3])
assert not long_enough([1, 2])
count_p
The count_p accepts two paramters. The predicate is evaluated and adds 1 to the count if True,
otherwise 0. The length_p evaluates the final count and is returned as the value of the
count_p itself.
In the next example we define a predicate that returns True if the number of elements in the iterable that are greater or equal 1, is exactly 1.
from predicate import count_p, ge_p, eq_p
predicate = count_p(predicate=ge_p(1), length_p=eq_p(1))
assert predicate([1])
assert not predicate([1, 3])
eq_false_p
This predicates tests if the argument is False.
from predicate import eq_false_p
assert eq_false_p(False)
assert not eq_false_p(True)
Note that this tests for the exact boolean value False. If you want to test for falsy values, see: is_falsy_p.
eq_p
This predicates tests for equality.
from predicate import eq_p
eq_2 = eq_p(2)
assert eq_2(2)
assert not eq_2(3)
eq_true_p
This predicates tests if the argument is True.
from predicate import eq_true_p
assert not eq_true_p(False)
assert eq_true_p(True)
Note that this tests for the exact boolean value True. If you want to test for falsy values, see: is_truthy_p.
fn_p
This predicate can be used to wrap any (lambda) function:
from predicate import fn_p
square_ge_2 = fn_p(lambda x: x * x >= 2)
assert not square_ge_2(1)
assert square_ge_2(2)
Both synchronous and async callables are supported.
from predicate import fn_p
async def is_positive(x: int) -> bool:
return x > 0
assert fn_p(is_positive)(5)
assert not fn_p(is_positive)(-1)
ge_le_p
This predicate tests if a value satisfies lower <= x <= upper.
from predicate import ge_le_p
between_2_and_5 = ge_le_p(2, 5)
assert between_2_and_5(2)
assert between_2_and_5(5)
assert not between_2_and_5(1)
assert not between_2_and_5(6)
ge_lt_p
This predicate tests if a value satisfies lower <= x < upper.
from predicate import ge_lt_p
predicate = ge_lt_p(2, 5)
assert predicate(2)
assert predicate(4)
assert not predicate(5)
ge_p
This predicates tests for greater or equal a value.
from predicate import ge_p
ge_2 = ge_p(2)
assert ge_2(2)
assert not ge_2(1)
gt_le_p
This predicate tests if a value satisfies lower < x <= upper.
from predicate import gt_le_p
predicate = gt_le_p(2, 5)
assert predicate(3)
assert predicate(5)
assert not predicate(2)
gt_lt_p
This predicate tests if a value satisfies lower < x < upper.
from predicate import gt_lt_p
predicate = gt_lt_p(2, 5)
assert predicate(3)
assert not predicate(2)
assert not predicate(5)
gt_p
This predicates tests for greater than a value.
from predicate import gt_p
gt_2 = gt_p(2)
assert not gt_2(2)
assert gt_2(3)
has_key_p
This predicate tests if a mapping contains at least one key satisfying a predicate. See has_key_p for full documentation and examples.
from predicate import eq_p, has_key_p
has_name = has_key_p(eq_p("name"))
assert has_name({"name": "Alice"})
assert not has_name({"age": 30})
has_length_p
This predicate tests the length of an iterable against another predicate.
from predicate import has_length_p, lt_p
has_length_lt_2 = has_length_p(lt_p(2))
assert not has_length_lt_2([1, 2, 3])
assert has_length_lt_2({1})
has_path_p
This predicate tests if a nested mapping contains a path where each step’s key satisfies the corresponding predicate.
from predicate import eq_p, has_path_p
# True if the dict has key "user" whose value has key "name"
has_user_name = has_path_p(eq_p("user"), eq_p("name"))
assert has_user_name({"user": {"name": "Alice"}})
assert not has_user_name({"user": {"age": 30}})
assert not has_user_name({"name": "Alice"})
implies_p
This predicate tests if one predicate implies another one.
from predicate import implies_p, ge_p
p = ge_p(2)
q = ge_p(3)
assert not implies(p, q)
assert implies(q, p)
is_bool_p
This predicate tests if the value is of type bool. Only True if the value is either False or True.
from predicate import is_bool_p
assert is_bool_p(False)
assert is_bool_p(True)
is_bytes_p
This predicate tests if the value is of type bytes.
from predicate import is_bytes_p
assert not is_bytes_p("hello")
assert not is_bytes_p(bytearray(b"hello"))
assert is_bytes_p(b"hello")
assert is_bytes_p(b"")
is_callable_p
This predicate tests if the value is of type Callable.
from predicate import is_callable_p
assert is_callable(is_callable)
assert is_callable(lambda x: x)
assert is_callable(str.upper)
is_close_p
This predicate tests if a float value is approximately equal to a target, accounting for
floating-point rounding errors. It wraps math.isclose() with configurable rel_tol
and abs_tol parameters.
from predicate import is_close_p
predicate = is_close_p(1.0)
assert predicate(1.0)
assert predicate(1.0 + 1e-10) # within default relative tolerance
assert not predicate(1.1)
Use abs_tol when comparing values near zero:
from predicate import is_close_p
near_zero = is_close_p(0.0, abs_tol=1e-6)
assert near_zero(1e-7)
assert not near_zero(1e-5)
is_complex_p
This predicate tests if the value is of type complex.
from predicate import is_complex_p
assert not is_complex(1)
assert is_complex(complex(1, 1))
assert is_complex(1 + 1j)
is_container_p
This predicate tests if the value is of type Container.
from predicate import is_container_p
assert is_container_p((1, 2, 3))
assert is_container_p([1, 2, 3])
assert is_container_p({1, 2, 3})
assert is_container_p({"one": 1, "two": 2, "three": 3})
assert is_container_p("one") # a string is also a container!
is_date_p
This predicate tests if the value is of type date.
Note that datetime is a subclass of date, so datetime values also match.
If you need to distinguish, combine with ~is_datetime_p.
from datetime import date, datetime
from predicate import is_date_p
assert is_date_p(date.today())
assert is_date_p(datetime.now()) # datetime is a subclass of date
assert not is_date_p("2024-01-01")
is_datetime_p
This predicate tests if the value is of type datetime.
from datetime import datetime
from predicate import is_datetime_p
assert is_datetime_p(datetime.now())
is_dict_p
This predicate tests if the value is of type dict.
from predicate import is_dict_p
assert is_dict_p({"one": 1, "two": 2, "three": 3})
is_dict_of_p
This predicate tests if the value is of type dict and the key and values match the predicates.
from predicate import is_dict_of_p, is_int_p, eq_p
# test for dictionaries that have keys x and y. The values should be integers
predicate = is_dict_of_p((eq_p("x"), is_int_p), (eq_p("y"), is_int_p))
assert predicate({"x": 1, "y": 7})
is_empty_p
This predicate tests if an iterable is empty.
from predicate import is_empty_p
assert is_empty_p(())
assert is_empty_p({})
assert is_empty_p([])
assert is_empty_p("")
is_even_p
This predicate tests if an integer is even.
from predicate import is_even_p
assert is_even_p(0)
assert is_even_p(4)
assert not is_even_p(3)
is_falsy_p
This predicate tests for falsy values, for example False, “”, {}, [], 0, etc.
from predicate import is_falsy_p
assert is_falsy_p(0)
assert is_falsy_p({})
is_finite_p
This predicate tests if the value is a finite number (i.e. not infinite and not NaN).
import math
from predicate import is_finite_p
assert not is_finite_p(math.inf)
assert not is_finite_p(math.nan)
assert is_finite_p(42)
is_float_p
This predicate tests if the value is of type float.
from predicate import is_float_p
assert not is_float_p(3)
assert is_float_p(3.14)
is_frozenset_p
This predicate tests if the value is of type frozenset.
from predicate import is_frozenset_p
assert not is_frozenset_p({1, 2, 3}) # a set, not a frozenset
assert is_frozenset_p(frozenset({1, 2, 3}))
assert is_frozenset_p(frozenset())
is_hashable_p
This predicate tests if the value is hashable.
from predicate import is_hashable_p
assert not is_hashable_p({})
assert is_hashable_p("foo")
is_inf_p
This predicate tests if the value is infinite.
import math
from predicate import is_inf_p
assert not is_inf_p(3)
assert is_inf_p(math.inf)
is_instance_p
This predicate tests if the value is an instance of one or more given classes.
from predicate import is_instance_p
is_int_or_str = is_instance_p(int, str)
assert is_int_or_str(42)
assert is_int_or_str("hello")
assert not is_int_or_str(3.14)
is_int_p
This predicate tests if the value is of type int.
from predicate import is_int_p
assert not is_int_p(3.14)
assert is_int_p(3)
is_iterable_of_p
This predicate tests if the value is an Iterable and all its elements satisfy the given predicate.
from predicate import is_iterable_of_p, is_int_p
all_ints = is_iterable_of_p(is_int_p)
assert all_ints([1, 2, 3])
assert all_ints((1,))
assert not all_ints([1, "two", 3])
is_iterable_p
This predicate tests if the value is of type Iterable.
from predicate import is_iterable_p
assert is_iterable_p([1, 2, 3])
assert is_iterable_p("hello")
assert not is_iterable_p(42)
is_list_of_p
This predicate predicate tests if the value if a list, where all items in the list conform to a given predicate.
from predicate import is_list_of_p, is_str_p
is_list_of_str = is_list_of_p(is_str_p)
assert not is_list_of_str(["one", "two", 3])
assert is_list_of_str(["foo"])
is_list_p
This predicate tests if the value is of type list.
from predicate import is_list_p
assert not is_list_p({1, 2, 3})
assert is_list_p([1, 2, 3])
is_mapping_p
This predicate tests if the value is a Mapping (i.e. any dict-like type).
from collections import OrderedDict
from predicate import is_mapping_p
assert is_mapping_p({"key": "value"})
assert is_mapping_p(OrderedDict())
assert not is_mapping_p([("key", "value")])
is_nan_p
This predicate tests if the value is NaN (not a number).
import math
from predicate import is_nan_p
assert not is_nan_p(1)
assert is_nan_p(math.nan)
is_none_p
This predicate tests if the value is None.
from predicate import is_none_p
assert not is_none_p(13)
assert is_none_p(None)
is_not_none_p
This predicate tests if the value is not None.
from predicate import is_not_none_p
assert not is_not_none_p(None)
assert is_not_none_p(13)
is_not_empty_p
This predicate tests if an iterable is not empty.
from predicate import is_not_empty_p
assert is_not_empty_p([1])
assert is_not_empty_p("hello")
assert not is_not_empty_p([])
assert not is_not_empty_p("")
is_number_p
This predicate tests if the value is a number (int, float, or complex).
bool values are excluded, consistent with how is_int_p works.
from predicate import is_number_p
assert is_number_p(42)
assert is_number_p(3.14)
assert is_number_p(1 + 2j)
assert not is_number_p(True) # bool is excluded
assert not is_number_p("42")
is_odd_p
This predicate tests if an integer is odd.
from predicate import is_odd_p
assert is_odd_p(1)
assert is_odd_p(7)
assert not is_odd_p(4)
is_path_p
This predicate tests if the value is a pathlib path.
Matches Path, PurePosixPath, PureWindowsPath, and any other PurePath subclass.
from pathlib import Path, PurePosixPath
from predicate import is_path_p
assert is_path_p(Path("/tmp/file.txt"))
assert is_path_p(PurePosixPath("/etc/hosts"))
assert not is_path_p("/tmp/file.txt") # a plain string is not a path
is_predicate_p
This predicate tests if the value is of type Predicate.
from predicate import is_predicate_p, eq_p
assert is_predicate_p(eq_p(1))
assert not is_predicate_p(42)
is_range_p
This predicate tests if value is a range.
from predicate import is_range_p
assert not is_range_p(0)
assert is_range_p(range(5))
is_sequence_p
This predicate tests if the value is a Sequence (list, tuple, str, bytes, range, etc.).
Note that dict and set are not sequences.
from predicate import is_sequence_p
assert is_sequence_p([1, 2, 3])
assert is_sequence_p((1, 2))
assert is_sequence_p("hello") # str is a sequence
assert is_sequence_p(range(5))
assert not is_sequence_p({1, 2, 3})
assert not is_sequence_p({"key": "value"})
is_set_of_p
This predicate predicate tests if the value if a set, where all items in the set conform to a given predicate.
from predicate import is_set_of_p, is_str_p
is_set_of_str = is_set_of_p(is_str_p)
assert not is_set_of_str({"one", "two", 3})
assert is_set_of_str({"foo"})
is_set_p
This predicate tests if the value is of type set.
from predicate import is_set_p
assert is_set_p({1, 2, 3})
assert not is_set_p([1, 2, 3])
assert not is_set_p(frozenset({1, 2, 3}))
is_str_p
This predicate tests if the value is of type str.
from predicate import is_str_p
assert not is_str_p(3.14)
assert is_str_p("foo")
is_subclass_p
This predicate tests if a class is a subclass of the given class.
from predicate import is_subclass_p
is_int_subclass = is_subclass_p(int)
assert is_int_subclass(bool) # bool is a subclass of int
assert not is_int_subclass(str)
is_time_p
This predicate tests if the value is of type datetime.time.
from datetime import time
from predicate import is_time_p
assert is_time_p(time(12, 30))
assert is_time_p(time(0, 0, 0))
assert not is_time_p("12:30")
is_timedelta_p
This predicate tests if the value is of type datetime.timedelta.
from datetime import timedelta
from predicate import is_timedelta_p
assert is_timedelta_p(timedelta(days=1))
assert is_timedelta_p(timedelta(seconds=3600))
assert not is_timedelta_p(3600)
is_truthy_p
This predicate tests for truthy values, for example True, “foo”, {“foo”}, [1], 13, etc.
from predicate import is_truthy_p
assert is_truthy_p(1)
assert is_truthy_p({"foo"})
is_tuple_of_p
This predicate tests if the value is a tuple of a specific structure, where each element matches the corresponding predicate.
from predicate import is_tuple_of_p, is_int_p, is_str_p
is_int_str_pair = is_tuple_of_p(is_int_p, is_str_p)
assert is_int_str_pair((1, "hello"))
assert not is_int_str_pair((1, 2))
assert not is_int_str_pair((1, "hello", "extra"))
is_tuple_p
This predicate tests if the value is of type tuple.
from predicate import is_tuple_p
assert is_tuple_p((1, 2, 3))
assert is_tuple_p(())
assert not is_tuple_p([1, 2, 3])
is_uuid_p
This predicate tests if the value is of type UUID.
from uuid import UUID, uuid4
from predicate import is_uuid_p
assert is_uuid_p(uuid4())
assert is_uuid_p(UUID("12345678-1234-5678-1234-567812345678"))
assert not is_uuid_p("12345678-1234-5678-1234-567812345678")
juxt_p
This predicate applies multiple predicates to the same value, collects the boolean results, and then evaluates
those results with an evaluate predicate.
In the simplest case, check if a value satisfies exactly two of four predicates:
from predicate import count_p, eq_p, is_int_p, is_str_p, juxt_p
p1 = is_int_p
p2 = is_str_p
p3 = eq_p(2)
p4 = eq_p("foo")
two_true = count_p(predicate=eq_p(True), length_p=eq_p(2))
predicate = juxt_p(p1, p2, p3, p4, evaluate=two_true)
assert predicate(2) # is_int_p and eq_p(2) are both True
assert predicate("foo") # is_str_p and eq_p("foo") are both True
assert not predicate(1) # only is_int_p is True
juxt_p also works with predicates that themselves accept iterables, enabling compound checks on the
same input in a single predicate:
from predicate import all_p, count_p, eq_p, exactly_one_p, is_int_p, juxt_p
all_int = all_p(is_int_p)
three_zeros = count_p(predicate=eq_p(0), length_p=eq_p(3))
one_true = exactly_one_p(predicate=eq_p(True))
predicate = juxt_p(all_int, three_zeros, evaluate=one_true)
assert predicate([1, 2, 3, 4]) # all ints, not 3 zeros → exactly one True
assert not predicate(
[1, 0, 2, 0, 3, 0]
) # all ints and 3 zeros → both True, so one_true fails
le_p
This predicates tests for less than or equal a value.
from predicate import le_p
le_2 = le_p(2)
assert le_2(2)
assert not le_2(3)
lt_p
This predicates tests for less than a value.
from predicate import lt_p
lt_2 = lt_p(2)
assert not lt_2(2)
assert lt_2(1)
match_p
This predicate tests if a sequence matches a series of predicates in order. Each predicate in the series is applied to the corresponding element.
from predicate import is_int_p, is_str_p, match_p
int_then_str = match_p(is_int_p, is_str_p)
assert int_then_str([1, "hello"])
assert not int_then_str([1, 2])
assert not int_then_str(["hello", 1])
ne_p
This predicate tests for non equality
from predicate import ne_p
ne_2 = ne_p(2)
assert not ne_2(2)
assert ne_2(3)
neg_p
This predicate tests if a number is negative (strictly less than zero).
from predicate import neg_p
assert neg_p(-1)
assert not neg_p(0)
assert not neg_p(1)
pos_p
This predicate tests if a number is positive (strictly greater than zero).
from predicate import pos_p
assert pos_p(1)
assert not pos_p(0)
assert not pos_p(-1)
raises_p
This predicate tests if a callable (thunk) raises an exception when called. Returns True if calling the thunk raises any exception, False otherwise. Both synchronous and async callables are supported.
from predicate import raises_p
assert raises_p(lambda: 1 / 0)
assert raises_p(lambda: int("x"))
assert not raises_p(lambda: 1)
Async functions are also supported:
async def fetch():
raise ConnectionError("unreachable")
async def ok():
return 42
assert raises_p(fetch)
assert not raises_p(ok)
raises_exception_p
This predicate tests if a callable raises a specific exception type when called. Returns True only if the exact exception type (or a subclass of it) is raised. Both synchronous and async callables are supported.
from predicate import raises_exception_p
assert raises_exception_p(ValueError)(lambda: int("x"))
assert raises_exception_p(Exception)(lambda: 1 / 0) # ZeroDivisionError is a subclass of Exception
assert not raises_exception_p(ValueError)(lambda: 1 / 0) # wrong exception type
assert not raises_exception_p(ValueError)(lambda: 1) # no exception raised
async def async_value_error():
raise ValueError("bad input")
assert raises_exception_p(ValueError)(async_value_error)
reduce_p
The reduce_p predicate threads an accumulator through an iterable. For each element x, it calls fn(acc, x) which returns a (new_acc, predicate) tuple. The element x must satisfy the returned predicate, and the accumulator advances for the next element. Returns True if all elements pass, or if the iterable is empty.
import sys
from predicate import reduce_p, ge_p
is_sorted_p = reduce_p(fn=lambda acc, x: (x, ge_p(acc)), initial=-sys.maxsize - 1)
assert is_sorted_p([])
assert is_sorted_p([1, 2, 3])
assert not is_sorted_p([1, 3, 2])
from predicate import reduce_p, eq_p, always_true_p
is_interval_3_p = reduce_p(fn=lambda acc, x: (x, eq_p(acc + 3) if acc else always_true_p), initial=None)
assert is_interval_3_p([1, 4, 7])
assert not is_interval_3_p([1, 3])
Both synchronous and async callables are supported.
import sys
from predicate import reduce_p, ge_p
async def sorted_step(acc, x):
return x, ge_p(acc)
is_sorted_p = reduce_p(fn=sorted_step, initial=-sys.maxsize - 1)
assert is_sorted_p([1, 2, 3])
assert not is_sorted_p([3, 1, 2])
regex_p
This predicate tests if a string matches a regular expression pattern.
from predicate import regex_p
is_phone = regex_p(r"\d{3}-\d{4}")
assert is_phone("555-1234")
assert not is_phone("hello")
tee_p
Predicate that always returns True, but is useful for handling side-effects.
from predicate import all_p, lt_p, tee_p
log = tee_p(print)
all_lt_2 = all_p(log | lt_p(2))
zero_p
Returns True of the value is zero, otherwise False.
from predicate import zero_p
assert zero_p(0)