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. |
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. |
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. |
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
Falseif the argument is 0, andTrueotherwise.>>> 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_nand 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
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]