fplib

A set of functions to program in python in a more functional style.

functional programming library

Functions

General-purpose

dictf(d) Returns a function with the behavior defined by a dictionary.
dictfd(d[, default]) Returns a function with the behavior defined by a dictionary, and a default value.
dictfdf(d[, defaultf]) Returns a function with the behavior defined by a dictionary, and by a default function.
mapf(f) Turns a function f into a function over lists, applying f to each element of the list.
filterf(predf) Returns a function that filters a list by a given predicate.
comp(*fs) Returns the composed function, functions being applied in the usual order (the last one applied first).
rcomp(*fs) Returns the compose function, with functions being applied in the reversed order (the first one applied first).
nest(f, n) Returns a function f nested n times.
idf(x) Returns the identity function.
constf(x) Returns a constant function.

Dictionaries

mapdictv(f, d) Maps a function over the values of a dictionary.
mapdictk(f, d) Maps a function over the keys of a dictionary.
mapdictkvkv(kvfk, kvfv, d) Maps two two-argument functions—having key and value as arguments—over the keys and the values of a dictionary.
filterdictk(f, d) Filters a dictionary based on its keys.
filterdictv(f, d) Filters a dictionary based on its values.
flip_dict(d) Flips the keys and the values of a dictionary.
update_dict(d, e[, copy]) Returns a new dictionary updated by another dictionary.

List-valued dictionaries

listvaldict(l) Creates a list-valued dictionary by aggregating values for the same keys into a list.
flip_listvaldict(lvd) Flips keys and values of a list-valued dictionary.
listvaldict_eq(lvda, lvdb) Tests whether two list-valued dictionaries are equal (ignoring the list order).

Structure

unlist1(ll) Flattens the outermost structure of inner lists.
relist1(unlisted, listed) Imposes a structure on a list.

Function application

npify(f) Transforms a function of multiple arguments into a function over a tuple.
denpify(f) Transforms a function over a tuple into a function over arguments.

Selectors

fst(x) Returns the first item of a collection.
snd(x) Returns the second item of a collection.
thr(x) Returns the third item of a collection.
last(l) Returns the last element of a collection.
nofirst(l) Returns a collection without its first element.
nolast(l) Returns a collection without its last element.

Predicates

zerolenp(e) Tests whether the len of an object is 0.

Zipping

zipe(l, e) Zips an element on the right side of a collection.
ezip(e, l) Zips an element on the left side of a collection.

Lists

heads(l) Returns all prefixes of a list.
tails(l) Returns all suffixes of a list.
sliding_window(l, n) Creates a sliding window of given length over a list.

Tuples

flip(tup) Flips the elements of a 2-element tuple.

Enumerations

lenum(l[, start]) Indexes a list from the left side.
renum(l[, start]) Indexes a list from the right side.

Mapping

emap(f, l) Maps a function over a list, returning both the argument and the result.
deepmap(f, dl) Performs a deep map over deeply nested list.
cachedmap(f, xs) Caches a function on the unique elements, then maps it over a list.

Filtering

dfilter(f, l) Splits the list into two sublists depending on the fulfilment of a criterion.

Functionalized operations

sjoin(strs[, s]) Function that joins strings.

Curried functions

startswithf(prefix) Returns a function that tests whether a string starts with a prefix.
replacef(s[, r]) Returns a function that replaces substrings with a replacement.
splitf(delim) Returns a function that splits string with a given delimiter.
fmtf(format) Returns a function that formats strings.
hasf(e) Returns a function which if applied with x tests whether x has e.
nothasf(e) Returns a function which if applied with x tests where ‘x’ does not have e.

Lookup

isinsetf(s) Returns a function which tests whether an element is in a set s.
fplib.idf(x)

Returns the identity function.

The identity function returns the element with which the function was applied.

Note

Useful commonly as an identity element of a function composition.

Parameters:x (any) – Element to apply the function with.
Returns:x – The same element as x.
Return type:any

Examples

>>> idf(1)
1
>>> idf([])
[]
fplib.constf(x)

Returns a constant function.

Suppose
f = constf(x).

Then, if f is applied with any y, it returns x.

Examples

>>> f = constf(10)
>>> f([])
10
>>> f(3)
10
fplib.dictf(d)

Returns a function with the behavior defined by a dictionary.

Suppose a dictionary d, and f = dictf(d).

Then, for a given x, the f(x) = d[x].

Examples

Consider a simple dictionary.

>>> d = {0: False, 1: True}

We can use it directly to get the values like:

>>> dictf(d)(0)
False

Furthermore, we can easily combine it with other functions, e.g., with the map().

>>> map(dictf(d), [0, 1, 0])
[False, True, False]
fplib.dictfd(d, default=None)

Returns a function with the behavior defined by a dictionary, and a default value.

Note

This function extends dictf().

See also

dictfdf() for argument-dependent behavior over non-specified values.

Examples

Let us define a function f that returns False if the argument is 0, and True otherwise.

>>> f = dictfd({0: False}, True)

We can map it over a list like this:

>>> map(f, [-1, 0, 1, 2])
[True, False, True, True]
fplib.dictfdf(d, defaultf=<function idf>)

Returns a function with the behavior defined by a dictionary, and by a default function.

Note

This function extends dictf().

See also

dictfd() for a constant behavior over non-specified values.

Examples

Suppose having a list of colors:

>>> colors = ['red', 'green', 'blue']

Now, imagine you would like to change the color ‘green’ to ‘yellow’ in the list:

>>> map(dictfdf({'green': 'yellow'}), colors)
['red', 'yellow', 'blue']
fplib.mapf(f)

Turns a function f into a function over lists, applying f to each element of the list.

Parameters:f (function) – The function.
Returns:g – Function that applies f over each element of a list.
Return type:function

Examples

Define a function f:

>>> f = lambda x: x + 1

We apply it over a list in the following way:

>>> mapf(f)([1, 2, 3])
[2, 3, 4]
fplib.filterf(predf)

Returns a function that filters a list by a given predicate.

Parameters:predf (function) – The predicate by which to filter.

Examples

Suppose a list of lists as follows:

>>> l = [[0, 1], [1, 2, 3]]

Let us retain those elements from each list that are even:

>>> map(filterf(lambda x: x % 2 == 1), l)
[[1], [1, 3]]
fplib.nest(f, n)

Returns a function f nested n times.

Suppose

g = nest(f, n),

then,

g(x) = f(f( … f(x) … )), with f being applied n times.
Parameters:
  • f (one-argument function) – The function to nest.
  • n (a non-negative number) – The number of applications of f.
Returns:

g

Return type:

a function of one argument

Examples

One can use nest, e.g., to navigate in the directory structure.

>>> import os
>>> d = "/home/user/dir"
>>> nest(os.path.dirname, 2)(d)
'/home'

When n is zero, the resulting function is the identity function.

>>> nest(os.path.dirname, 0)(d)
'/home/user/dir'
fplib.comp(*fs)

Returns the composed function, functions being applied in the usual order (the last one applied first).

Suppose fs refers to functions

f_1, f_2, …, f_n

and consider a function g defined as

g = comp(f_1, f_2, …, f_n).

Then g(x) behaves as follows:

g(x) = f_1(f_2( … (f_n(x)) … )).
Parameters:fs (functions of one argument) – The functions to compose.
Returns:g – The composed function.
Return type:function of one argument

Note

If the argument list is empty, returns the identity function.

See also

rcomp() for composition in the reversed order.

Examples

Let us define some functions first:

>>> fa = lambda x: x + 2
>>> fb = lambda x: x * 2

Then let us compose them:

>>> g = comp(fa, fb)

Now we can apply the function g:

>>> g(10) # (10 * 2) + 2
22

Note the difference if we compose them in the opposite order:

>>> h = comp(fb, fa)
>>> h(10) # (10 + 2) * 2
24
fplib.rcomp(*fs)

Returns the compose function, with functions being applied in the reversed order (the first one applied first).

See also

comp() for composion in the usual order.

fplib.mapdictv(f, d)

Maps a function over the values of a dictionary.

Examples

Let us define a simple dictionary:

>>> d = {'a': 0}

Now, we can map over its values:

>>> mapdictv(lambda x: x + 1, d)
{'a': 1}
fplib.mapdictk(f, d)

Maps a function over the keys of a dictionary.

Note

If f maps different keys k_1, … k_n into the same key k, the dictionary will contain only one of them.

Examples

Let us define a simple dictionary:

>>> d = {1: 'a'}
>>> mapdictk(lambda x: x + 1, d)
{2: 'a'}
fplib.mapdictkvkv(kvfk, kvfv, d)

Maps two two-argument functions—having key and value as arguments—over the keys and the values of a dictionary.

Suppose a dictionary

d = {k_1: v_1, …, k_n: v_n}.

The function builds a dictionary e, with all the pairs as specified for the k_i and v_i:

e = { …, kvfk(k_i, v_i): kvfv(k_i, v_i), …}.
Parameters:
  • kvfk (function of two arguments --- key and value) – A function to apply over the key and the value, giving the new key.
  • kvfv (function of two arguments --- key and value) – A function to apply over the key and the value, giving the new value.

Examples

Consider a dictionary d:

>>> d = {1: 'a', 2: 'b', 3: 'c'}

We can, e.g., rebuild the dictionary as follows:

>>> md = mapdictkvkv(lambda k, v: k, lambda k, v: v, d)
>>> md == d
True

We can, e.g., reverse the dictionary as follows:

>>> rd = mapdictkvkv(lambda k, v: v, lambda k, v: k, d)
>>> rd == {'a': 1, 'b': 2, 'c': 3}
True
fplib.filterdictk(f, d)

Filters a dictionary based on its keys.

Examples

Suppose the following predicate:

>>> is_even = lambda x: x % 2 == 0

Define a dictionary:

>>> d = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}

We can filter the dictionary by its keys:

>>> filterdictk(is_even, d)
{0: 'a', 2: 'c'}
fplib.filterdictv(f, d)

Filters a dictionary based on its values.

See also

filterdictk() for filtering based on the keys.

fplib.update_dict(d, e, copy=True)

Returns a new dictionary updated by another dictionary.

Examples

Consider a dictionary d which we want to update:

>>> d = {0: 'a', 1: 'b'}

Now consider the dictionary for update:

>>> e = {1: 'c', 2: 'd'}

We can update the d as follows:

>>> f = update_dict(d, e)
>>> f
{0: 'a', 1: 'c', 2: 'd'}

Note that the previous dictionary is unchanged:

>>> d
{0: 'a', 1: 'b'}
fplib.flip_dict(d)

Flips the keys and the values of a dictionary.

Note

If multiple keys k_1, …, k_n with the same value v exist, only one (say, k_i) will be present (as a value) in the flipped dictionary.

See also

For a reversible dictionary, see listvaldict().

Examples

>>> d = {0: 'a', 1: 'b', 2: 'c'}
>>> flip_dict(d) == {'a': 0, 'b': 1, 'c': 2}
True
fplib.listvaldict(l)

Creates a list-valued dictionary by aggregating values for the same keys into a list.

Examples

>>> l = [(0, 'a'), (0, 'b'), (1, 'c')]
>>> listvaldict(l)
{0: ['a', 'b'], 1: ['c']}
fplib.flip_listvaldict(lvd)

Flips keys and values of a list-valued dictionary.

Examples

Define a list-valued dictionary:

>>> lvd = {0: ['a', 'b'], 1: ['c'], 2: ['a']}

Let’s flip it.

>>> flvd = flip_listvaldict(lvd)
>>> flvd == {'a': [0, 2], 'b': [0], 'c': [1]}
True

If we flip it again, we get the original one, except for the possible differences in the order of the list-values.

>>> fflvd = flip_listvaldict(flvd)
>>> listvaldict_eq(fflvd, lvd)
True
fplib.listvaldict_eq(lvda, lvdb)

Tests whether two list-valued dictionaries are equal (ignoring the list order).

Example

Let us define two list-value dictionaries that differ just in the order of elements for particular key(s).

>>> lvda = {0: ['a', 'b'], 1: ['c']}
>>> lvdb = {0: ['b', 'a'], 1: ['c']}
>>> listvaldict_eq(lvda, lvdb)
True
fplib.unlist1(ll)

Flattens the outermost structure of inner lists.

Examples

Let us define a list of inner lists:

>>> ll = [[0, 1], [2], [], [3, 4]]

Now we can unlist it:

>>> unlist1(ll)
[0, 1, 2, 3, 4]

Note that if we had multiple levels of lists, such as in this case,

>>> lll = [[[0, 1]], [2, 3]]

only one level of flattening happens.

>>> unlist1(lll)
[[0, 1], 2, 3]
fplib.relist1(unlisted, listed)

Imposes a structure on a list.

Examples

Let us define the structure of the list.

>>> ll = [[0, 1], [2]]

Let us have an unstructured list, for which we want to impose the structure.

>>> ul = ['a', 'b', 'c']

Now let us impose the structure of ll on ul.

>>> relist1(ul, ll)
[['a', 'b'], ['c']]
fplib.npify(f)

Transforms a function of multiple arguments into a function over a tuple.

Suppose

g = npify(f).

Then g((arg_1, arg_2, …)) = f(arg_1, arg_2, …).

Example

>>> import math
>>> math.pow(2, 3)
8.0
>>> f = npify(math.pow)
>>> f((2, 3))
8.0
fplib.denpify(f)

Transforms a function over a tuple into a function over arguments.

Suppose that

g = denpify(f),

then

g(a_1, a_2, …, a_n) = f((a_1, a_2, …, a_n)).

Examples

>>> flip((0, 1))
(1, 0)
>>> f = denpify(flip)
>>> f(0, 1) # note the the argument is *not* a tuple
(1, 0)
fplib.fst(x)

Returns the first item of a collection.

Examples

>>> fst([0, 1, 2])
0
fplib.snd(x)

Returns the second item of a collection.

Examples

>>> snd([0, 1, 2])
1
fplib.thr(x)

Returns the third item of a collection.

Examples

>>> thr([0, 1, 2])
2
fplib.last(l)

Returns the last element of a collection.

Note

Useful when we do not want to have numbers in the code. Furthermore, it can be directly used in the function composition.

Examples

>>> last([1, 2, 3])
3
fplib.nofirst(l)

Returns a collection without its first element.

Examples

>>> nofirst([0, 1, 2])
[1, 2]
>>> nofirst([])
[]
fplib.nolast(l)

Returns a collection without its last element.

Examples

>>> nolast([0, 1, 2])
[0, 1]
>>> nolast([])
[]
fplib.zerolenp(e)

Tests whether the len of an object is 0.

Examples

>>> zerolenp([])
True
>>> zerolenp('')
True
>>> zerolenp([0])
False
fplib.zipe(l, e)

Zips an element on the right side of a collection.

Examples

Let us define a list l:

>>> l = [0, 1, 2]

Let us zip an element ‘id’ on the right side of each element in l.

>>> zipe(l, 'id')
[(0, 'id'), (1, 'id'), (2, 'id')]

See also

ezip() for zipping the element from the left side.

fplib.ezip(e, l)

Zips an element on the left side of a collection.

Examples

Let us define a list l:

>>> l = [0, 1, 2]

Let us zip an element ‘id’ for each element of the l.

>>> ezip('id', l)
[('id', 0), ('id', 1), ('id', 2)]
fplib.emap(f, l)

Maps a function over a list, returning both the argument and the result.

Examples

>>> f = lambda x: x + 1
>>> emap(f, [0, 1, 2])
[(0, 1), (1, 2), (2, 3)]
fplib.deepmap(f, dl)

Performs a deep map over deeply nested list.

Examples

Let us define a deep list:

>>> dl = [0, 1, [2, [3], 4]]

Now we can apply the function over each leaf of the list:

>>> deepmap(lambda x: x + 1, dl)
[1, 2, [3, [4], 5]]
fplib.cachedmap(f, xs)

Caches a function on the unique elements, then maps it over a list.

Note

Uses internally set() to get unique elements.

Examples

>>> def f(x): print("f called with %d" % x); return x
>>> cachedmap(f, [0, 0, 1, 2])
f called with 0
f called with 1
f called with 2
[0, 0, 1, 2]
fplib.heads(l)

Returns all prefixes of a list.

Examples

>>> heads([0, 1, 2])
[[], [0], [0, 1], [0, 1, 2]]
fplib.tails(l)

Returns all suffixes of a list.

Examples

>>> tails([0, 1, 2])
[[0, 1, 2], [1, 2], [2], []]
fplib.sliding_window(l, n)

Creates a sliding window of given length over a list.

Examples

>>> l = range(5)
>>> sliding_window(l, 2)
[[0, 1], [1, 2], [2, 3], [3, 4]]
fplib.dfilter(f, l)

Splits the list into two sublists depending on the fulfilment of a criterion.

Examples

Define a function which tests whether an argument is even number.

>>> is_even = lambda x: x % 2 == 0

Now we can split the list like this:

>>> dfilter(is_even, [0, 1, 2, 3, 4, 5])
([0, 2, 4], [1, 3, 5])
fplib.flip(tup)

Flips the elements of a 2-element tuple.

Examples

>>> flip((0, 1))
(1, 0)
fplib.lenum(l, start=0)

Indexes a list from the left side.

Examples

>>> lenum(['a', 'b', 'c'])
[(0, 'a'), (1, 'b'), (2, 'c')]
fplib.renum(l, start=0)

Indexes a list from the right side.

Examples

>>> renum(["a", "b", "c"])
[('a', 0), ('b', 1), ('c', 2)]
fplib.sjoin(strs, s='')

Function that joins strings.

Examples

Consider a list l of strings.

>>> l = ["abc", "def"]

We can join the strings in l as:

>>> sjoin(l)
'abcdef'

Or with a joiner as:

>>> sjoin(l, " ")
'abc def'
fplib.startswithf(prefix)

Returns a function that tests whether a string starts with a prefix.

Examples

>>> f = startswithf('__')
>>> f('abc')
False
>>> f('__name__')
True
fplib.endswithf(suffix)

Returns a function that tests whether a string ends with a suffix.

Examples

>>> f = endswithf('.txt')
>>> f('abc')
False
>>> f('abc.txt')
True
fplib.replacef(s, r='')

Returns a function that replaces substrings with a replacement.

Examples

>>> f = replacef('inside', 'outside')
>>> f('Thankfully, I have spent the day inside.')
'Thankfully, I have spent the day outside.'
fplib.splitf(delim)

Returns a function that splits string with a given delimiter.

Examples

>>> f = splitf(", ")
>>> f('apples, pears, oranges')
['apples', 'pears', 'oranges']
fplib.fmtf(format)

Returns a function that formats strings.

>>> f = fmtf("%.2f")
>>> f(0.5)
'0.50'
fplib.hasf(e)

Returns a function which if applied with x tests whether x has e.

Examples

>>> filter(hasf("."), ['statement', 'A sentence.'])
['A sentence.']
fplib.nothasf(e)

Returns a function which if applied with x tests where ‘x’ does not have e.

See also

hasf().

Examples

>>> filter(nothasf("."), ['statement', 'A sentence.'])
['statement']
fplib.isinsetf(s)

Returns a function which tests whether an element is in a set s.

Examples

>>> colors = ['red', 'green', 'blue']
>>> f = isinsetf(colors)
>>> map(f, ['yellow', 'green'])
[False, True]