Funcy
A fancy and practical functional tools
Install / Use
/learn @Suor/FuncyREADME
Funcy |Build Status|
A collection of fancy functional tools focused on practicality.
Inspired by clojure, underscore and my own abstractions. Keep reading to get an overview
or read the docs <https://funcy.readthedocs.io/>.
Or jump directly to cheatsheet <https://funcy.readthedocs.io/en/stable/cheatsheet.html>.
Works with Python 3.4+ and pypy3.
Installation
::
pip install funcy
Overview
Import stuff from funcy to make things happen:
.. code:: python
from funcy import whatever, you, need
Merge collections of same type (works for dicts, sets, lists, tuples, iterators and even strings):
.. code:: python
merge(coll1, coll2, coll3, ...)
join(colls)
merge_with(sum, dict1, dict2, ...)
Walk through collection, creating its transform (like map but preserves type):
.. code:: python
walk(str.upper, {'a', 'b'}) # {'A', 'B'}
walk(reversed, {'a': 1, 'b': 2}) # {1: 'a', 2: 'b'}
walk_keys(double, {'a': 1, 'b': 2}) # {'aa': 1, 'bb': 2}
walk_values(inc, {'a': 1, 'b': 2}) # {'a': 2, 'b': 3}
Select a part of collection:
.. code:: python
select(even, {1,2,3,10,20}) # {2,10,20}
select(r'^a', ('a','b','ab','ba')) # ('a','ab')
select_keys(callable, {str: '', None: None}) # {str: ''}
compact({2, None, 1, 0}) # {1,2}
Manipulate sequences:
.. code:: python
take(4, iterate(double, 1)) # [1, 2, 4, 8]
first(drop(3, count(10))) # 13
lremove(even, [1, 2, 3]) # [1, 3]
lconcat([1, 2], [5, 6]) # [1, 2, 5, 6]
lcat(map(range, range(4))) # [0, 0, 1, 0, 1, 2]
lmapcat(range, range(4)) # same
flatten(nested_structure) # flat iter
distinct('abacbdd') # iter('abcd')
lsplit(odd, range(5)) # ([1, 3], [0, 2, 4])
lsplit_at(2, range(5)) # ([0, 1], [2, 3, 4])
group_by(mod3, range(5)) # {0: [0, 3], 1: [1, 4], 2: [2]}
lpartition(2, range(5)) # [[0, 1], [2, 3]]
chunks(2, range(5)) # iter: [0, 1], [2, 3], [4]
pairwise(range(5)) # iter: [0, 1], [1, 2], ...
And functions:
.. code:: python
partial(add, 1) # inc
curry(add)(1)(2) # 3
compose(inc, double)(10) # 21
complement(even) # odd
all_fn(isa(int), even) # is_even_int
one_third = rpartial(operator.div, 3.0)
has_suffix = rcurry(str.endswith, 2)
Create decorators easily:
.. code:: python
@decorator
def log(call):
print(call._func.__name__, call._args)
return call()
Abstract control flow:
.. code:: python
walk_values(silent(int), {'a': '1', 'b': 'no'})
# => {'a': 1, 'b': None}
@once
def initialize():
"..."
with suppress(OSError):
os.remove('some.file')
@ignore(ErrorRateExceeded)
@limit_error_rate(fails=5, timeout=60)
@retry(tries=2, errors=(HttpError, ServiceDown))
def some_unreliable_action(...):
"..."
class MyUser(AbstractBaseUser):
@cached_property
def public_phones(self):
return self.phones.filter(public=True)
Ease debugging:
.. code:: python
squares = {tap(x, 'x'): tap(x * x, 'x^2') for x in [3, 4]}
# x: 3
# x^2: 9
# ...
@print_exits
def some_func(...):
"..."
@log_calls(log.info, errors=False)
@log_errors(log.exception)
def some_suspicious_function(...):
"..."
with print_durations('Creating models'):
Model.objects.create(...)
# ...
# 10.2 ms in Creating models
And much more <https://funcy.readthedocs.io/>_.
Dive in
Funcy is an embodiment of ideas I explain in several essays:
Why Every Language Needs Its Underscore <https://suor.github.io/blog/2014/06/22/why-every-language-needs-its-underscore/>_Functional Python Made Easy <https://suor.github.io/blog/2013/10/13/functional-python-made-easy/>_Abstracting Control Flow <https://suor.github.io/blog/2013/10/08/abstracting-control-flow/>_Painless Decorators <https://suor.github.io/blog/2013/11/03/painless-decorators/>_
Related Projects
- https://pypi.org/project/funcy-chain/
- https://pypi.org/project/funcy-pipe/
Running tests
To run the tests using your default python:
::
pip install -r test_requirements.txt
pytest
To fully run tox you need all the supported pythons to be installed. These are
3.4+ and PyPy3. You can run it for particular environment even in absense
of all of the above::
tox -e py310
tox -e pypy3
tox -e lint
.. |Build Status| image:: https://github.com/Suor/funcy/actions/workflows/test.yml/badge.svg :target: https://github.com/Suor/funcy/actions/workflows/test.yml?query=branch%3Amaster
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
claude-opus-4-5-migration
109.5kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
model-usage
349.2kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
