Funcy
=====
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 <http://funcy.readthedocs.org/>`_.
Or jump directly to `cheatsheet <http://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 <http://funcy.readthedocs.org/>`_.
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/>`_
Running tests
--------------
To run the tests using your default python:
::
pip install -r test_requirements.txt
py.test
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
Raw data
{
"_id": null,
"home_page": "http://github.com/Suor/funcy",
"name": "funcy",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Alexander Schepanovski",
"author_email": "suor.web@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/70/b8/c6081521ff70afdff55cd9512b2220bbf4fa88804dae51d1b57b4b58ef32/funcy-2.0.tar.gz",
"platform": null,
"description": "Funcy \n=====\n\nA collection of fancy functional tools focused on practicality.\n\nInspired by clojure, underscore and my own abstractions. Keep reading to get an overview\nor `read the docs <http://funcy.readthedocs.org/>`_.\nOr jump directly to `cheatsheet <http://funcy.readthedocs.io/en/stable/cheatsheet.html>`_.\n\nWorks with Python 3.4+ and pypy3.\n\n\nInstallation\n-------------\n\n::\n\n pip install funcy\n\n\nOverview\n--------------\n\nImport stuff from funcy to make things happen:\n\n.. code:: python\n\n from funcy import whatever, you, need\n\n\nMerge collections of same type\n(works for dicts, sets, lists, tuples, iterators and even strings):\n\n.. code:: python\n\n merge(coll1, coll2, coll3, ...)\n join(colls)\n merge_with(sum, dict1, dict2, ...)\n\n\nWalk through collection, creating its transform (like map but preserves type):\n\n.. code:: python\n\n walk(str.upper, {'a', 'b'}) # {'A', 'B'}\n walk(reversed, {'a': 1, 'b': 2}) # {1: 'a', 2: 'b'}\n walk_keys(double, {'a': 1, 'b': 2}) # {'aa': 1, 'bb': 2}\n walk_values(inc, {'a': 1, 'b': 2}) # {'a': 2, 'b': 3}\n\n\nSelect a part of collection:\n\n.. code:: python\n\n select(even, {1,2,3,10,20}) # {2,10,20}\n select(r'^a', ('a','b','ab','ba')) # ('a','ab')\n select_keys(callable, {str: '', None: None}) # {str: ''}\n compact({2, None, 1, 0}) # {1,2}\n\n\nManipulate sequences:\n\n.. code:: python\n\n take(4, iterate(double, 1)) # [1, 2, 4, 8]\n first(drop(3, count(10))) # 13\n\n lremove(even, [1, 2, 3]) # [1, 3]\n lconcat([1, 2], [5, 6]) # [1, 2, 5, 6]\n lcat(map(range, range(4))) # [0, 0, 1, 0, 1, 2]\n lmapcat(range, range(4)) # same\n flatten(nested_structure) # flat iter\n distinct('abacbdd') # iter('abcd')\n\n lsplit(odd, range(5)) # ([1, 3], [0, 2, 4])\n lsplit_at(2, range(5)) # ([0, 1], [2, 3, 4])\n group_by(mod3, range(5)) # {0: [0, 3], 1: [1, 4], 2: [2]}\n\n lpartition(2, range(5)) # [[0, 1], [2, 3]]\n chunks(2, range(5)) # iter: [0, 1], [2, 3], [4]\n pairwise(range(5)) # iter: [0, 1], [1, 2], ...\n\n\nAnd functions:\n\n.. code:: python\n\n partial(add, 1) # inc\n curry(add)(1)(2) # 3\n compose(inc, double)(10) # 21\n complement(even) # odd\n all_fn(isa(int), even) # is_even_int\n\n one_third = rpartial(operator.div, 3.0)\n has_suffix = rcurry(str.endswith, 2)\n\n\nCreate decorators easily:\n\n.. code:: python\n\n @decorator\n def log(call):\n print call._func.__name__, call._args\n return call()\n\n\nAbstract control flow:\n\n.. code:: python\n\n walk_values(silent(int), {'a': '1', 'b': 'no'})\n # => {'a': 1, 'b': None}\n\n @once\n def initialize():\n \"...\"\n\n with suppress(OSError):\n os.remove('some.file')\n\n @ignore(ErrorRateExceeded)\n @limit_error_rate(fails=5, timeout=60)\n @retry(tries=2, errors=(HttpError, ServiceDown))\n def some_unreliable_action(...):\n \"...\"\n\n class MyUser(AbstractBaseUser):\n @cached_property\n def public_phones(self):\n return self.phones.filter(public=True)\n\n\nEase debugging:\n\n.. code:: python\n\n squares = {tap(x, 'x'): tap(x * x, 'x^2') for x in [3, 4]}\n # x: 3\n # x^2: 9\n # ...\n\n @print_exits\n def some_func(...):\n \"...\"\n\n @log_calls(log.info, errors=False)\n @log_errors(log.exception)\n def some_suspicious_function(...):\n \"...\"\n\n with print_durations('Creating models'):\n Model.objects.create(...)\n # ...\n # 10.2 ms in Creating models\n\n\nAnd `much more <http://funcy.readthedocs.org/>`_.\n\n\nDive in\n-------\n\nFuncy is an embodiment of ideas I explain in several essays:\n\n- `Why Every Language Needs Its Underscore <https://suor.github.io/blog/2014/06/22/why-every-language-needs-its-underscore/>`_\n- `Functional Python Made Easy <https://suor.github.io/blog/2013/10/13/functional-python-made-easy/>`_\n- `Abstracting Control Flow <https://suor.github.io/blog/2013/10/08/abstracting-control-flow/>`_\n- `Painless Decorators <https://suor.github.io/blog/2013/11/03/painless-decorators/>`_\n\n\nRunning tests\n--------------\n\nTo run the tests using your default python:\n\n::\n\n pip install -r test_requirements.txt\n py.test\n\nTo fully run ``tox`` you need all the supported pythons to be installed. These are\n3.4+ and PyPy3. You can run it for particular environment even in absense\nof all of the above::\n\n tox -e py310\n tox -e pypy3\n tox -e lint\n\n\n.. |Build Status| image:: https://github.com/Suor/funcy/actions/workflows/test.yml/badge.svg\n :target: https://github.com/Suor/funcy/actions/workflows/test.yml?query=branch%3Amaster\n\n\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "A fancy and practical functional tools",
"version": "2.0",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d508c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30",
"md5": "c7f45b9e922ea90b628a36a78cc50518",
"sha256": "53df23c8bb1651b12f095df764bfb057935d49537a56de211b098f4c79614bb0"
},
"downloads": -1,
"filename": "funcy-2.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "c7f45b9e922ea90b628a36a78cc50518",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 30891,
"upload_time": "2023-03-28T06:22:42",
"upload_time_iso_8601": "2023-03-28T06:22:42.576888Z",
"url": "https://files.pythonhosted.org/packages/d5/08/c2409cb01d5368dcfedcbaffa7d044cc8957d57a9d0855244a5eb4709d30/funcy-2.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "70b8c6081521ff70afdff55cd9512b2220bbf4fa88804dae51d1b57b4b58ef32",
"md5": "ed5eea5f31fdb2c562dc32cadb8d0742",
"sha256": "3963315d59d41c6f30c04bc910e10ab50a3ac4a225868bfa96feed133df075cb"
},
"downloads": -1,
"filename": "funcy-2.0.tar.gz",
"has_sig": false,
"md5_digest": "ed5eea5f31fdb2c562dc32cadb8d0742",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 537931,
"upload_time": "2023-03-28T06:22:46",
"upload_time_iso_8601": "2023-03-28T06:22:46.764877Z",
"url": "https://files.pythonhosted.org/packages/70/b8/c6081521ff70afdff55cd9512b2220bbf4fa88804dae51d1b57b4b58ef32/funcy-2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-28 06:22:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "Suor",
"github_project": "funcy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"test_requirements": [],
"tox": true,
"lcname": "funcy"
}