Funcy
Funcy is a Python library offering a collection of practical functional tools, inspired by Clojure and Underscore.js. It aims to simplify data manipulation and function composition, providing utilities for working with collections, dictionaries, and functions in a functional style. The current stable version is 2.0, released in March 2023, and it supports Python 3.4+ and PyPy3.
Warnings
- breaking When migrating from Python 2 to Python 3, `funcy` versions 0.9 and above adopted Python 3's 'iterator by default' convention for functions like `map` and `filter`. This means functions that previously returned lists might now return iterators, potentially breaking code expecting list results.
- gotcha Many Funcy functions that operate on sequences offer two versions: one that returns an iterator (e.g., `flatten`, `chunks`) and one that returns an immediate list (e.g., `lflatten`, `lchunks`). Confusing these can lead to unexpected behavior or performance issues.
- gotcha Funcy does not natively support method chaining for data transformations in the same way some other functional libraries or Pandas do. If you expect to call `funcy` functions as methods on data structures, it won't work out of the box.
- gotcha While some older examples or quick experiments might use `from funcy import *`, this practice is discouraged for production code. Funcy is a comprehensive library, and wildcard imports can easily lead to namespace collisions and make code harder to read and debug.
Install
-
pip install funcy
Imports
- lmap
from funcy import lmap
- lflatten
from funcy import lflatten
- merge
from funcy import merge
Quickstart
from funcy import lmap, lfilter, lflatten, merge, first, drop, count
# Flatten a nested list
data = [1, 2, [3, 4], 5, [6, [7, 8]]]
flattened = lflatten(data)
print(f"Flattened: {flattened}")
# Map and filter a sequence
numbers = [1, 2, 3, 4, 5, 6]
even_squares = lmap(lambda x: x**2, lfilter(lambda x: x % 2 == 0, numbers))
print(f"Even squares: {even_squares}")
# Merge dictionaries
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged_dict = merge(dict1, dict2)
print(f"Merged dict: {merged_dict}")
# Get the Nth item from an infinite sequence using iterators
third_item = first(drop(2, count(1)))
print(f"Third item in count(1): {third_item}")