In [45]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
A list comprehension is eager.
In [20]:
[x*x for x in range(3)]
Out[20]:
A generator expression is lazy.
In [21]:
(x*x for x in range(3))
Out[21]:
You can use generators as iterators.
In [22]:
g = (x*x for x in range(3))
In [23]:
next(g)
Out[23]:
In [24]:
next(g)
Out[24]:
In [25]:
next(g)
Out[25]:
In [26]:
next(g)
A generator is single use.
In [ ]:
for i in g:
print(i, end=", ")
In [28]:
g = (x*x for x in range(3))
for i in g:
print(i, end=", ")
The list constructor forces evaluation of the generator.
In [30]:
list(x*x for x in range(3))
Out[30]:
An eager function.
In [3]:
def eager_updown(n):
xs = []
for i in range(n):
xs.append(i)
for i in range(n, -1, -1):
xs.append(i)
return xs
In [4]:
eager_updown(3)
Out[4]:
A lazy generator.
In [5]:
def lazy_updown(n):
for i in range(n):
yield i
for i in range(n, -1, -1):
yield i
In [6]:
lazy_updown(3)
Out[6]:
In [7]:
list(lazy_updown(3))
Out[7]:
A pure function is like a mathematical function. Given the same inputs, it always returns the same output, and has no side effects.
In [32]:
def pure(alist):
return [x*x for x in alist]
An impure function has side effects.
In [39]:
def impure(alist):
for i in range(len(alist)):
alist[i] = alist[i]*alist[i]
return alist
In [40]:
xs = [1,2,3]
In [41]:
ys = pure(xs)
print(xs, ys)
In [42]:
ys = impure(xs)
print(xs, ys)
In [57]:
def f1(n):
return n//2 if n % 2==0 else n*3+1
In [58]:
def f2(n):
return np.random.random(n)
In [59]:
def f3(n):
n = 23
return n
In [60]:
def f4(a, n=[]):
n.append(a)
return n
In [61]:
list(map(f1, range(10)))
Out[61]:
In [63]:
list(filter(lambda x: x % 2 == 0, range(10)))
Out[63]:
In [62]:
from functools import reduce
In [66]:
reduce(lambda x, y: x + y, range(10), 0)
Out[66]:
In [68]:
reduce(lambda x, y: x + y, [[1,2], [3,4], [5,6]], [])
Out[68]:
In [69]:
import operator as op
In [71]:
reduce(op.mul, range(1, 6), 1)
Out[71]:
In [72]:
list(map(op.itemgetter(1), [[1,2,3],[4,5,6],[7,8,9]]))
Out[72]:
In [73]:
import itertools as it
In [76]:
list(it.combinations(range(1,6), 3))
Out[76]:
Generate all Boolean combinations
In [85]:
list(it.product([0,1], repeat=3))
Out[85]:
In [78]:
list(it.starmap(op.add, zip(range(5), range(5))))
Out[78]:
In [79]:
list(it.takewhile(lambda x: x < 3, range(10)))
Out[79]:
In [100]:
data = sorted('the quick brown fox jumps over the lazy dog'.split(), key=len)
for k, g in it.groupby(data, key=len):
print(k, list(g))
In [101]:
import toolz as tz
In [104]:
list(tz.partition(3, range(10)))
Out[104]:
In [106]:
list(tz.partition(3, range(10), pad=None))
Out[106]:
In [151]:
n = 30
dna = ''.join(np.random.choice(list('ACTG'), n))
dna
Out[151]:
In [152]:
tz.frequencies(tz.sliding_window(2, dna))
Out[152]:
In [153]:
from toolz import curried as c
In [157]:
tz.pipe(
dna,
c.sliding_window(2), # using curry
c.frequencies,
)
Out[157]:
In [164]:
composed = tz.compose(
c.frequencies,
c.sliding_window(2),
)
In [165]:
composed(dna)
Out[165]:
In [184]:
m = 10000
n = 300
dnas = (''.join(np.random.choice(list('ACTG'), n, p=[.1, .2, .3, .4]))
for i in range(m))
dnas
Out[184]:
In [185]:
tz.merge_with(sum,
tz.map(
composed,
dnas
)
)
Out[185]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: