{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Functions" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%load_ext rpy2.ipython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arguments" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, b, c):\n", " return a, b, c" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3, 2, 1)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(3, 2, 1)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(c=3, b=2, a=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Defaults" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a=1, b=2, c=3):\n", " return a, b, c" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(10, 2, 3)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(10)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 30)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(c=30)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Variadic arguments" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, *args, **kwargs):\n", " return a, args, kwargs" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, (2, 3), {})" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(10, (1, 2, 3), {'d': 4, 'e': 5, 'f': 6})" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(10, 1, 2, 3, d=4, e=5, f=6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mandatory named arguments" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, *, b, c):\n", " return(a, b, c)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "f() takes 1 positional argument but 3 were given", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: f() takes 1 positional argument but 3 were given" ] } ], "source": [ "f(1, 2, 3)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1, b=2, c=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Watch out for mutable default arguments" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, b=[]):\n", " b.append(a)\n", " return a, b" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, [1])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### The default list argument is set at function definition and persists across function calls" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, [1, 2])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, [5, 4, 3, 2])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2, b=[5,4,3])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Idiom for mutable default arguments" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def f(a, b=None):\n", " if b is None:\n", " b = []\n", " b.append(a)\n", " return a, b" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, [1])" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, [2])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functions are first-class objects" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "funcs = [sum, len, hash]" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "4\n", "6312109104812642389\n" ] } ], "source": [ "for func in funcs:\n", " print(func(range(1,5)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Anonymous functions" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "funcs = [lambda x: x, lambda x: x**2, lambda x: x**3]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n", "100\n", "1000\n" ] } ], "source": [ "for func in funcs:\n", " print(func(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Higher-order function" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "#### A function that accepts a function as argument" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, b, g):\n", " return g(a, b)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1, 2, lambda x, y: x + y)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f(1, 2, lambda x, y: x * y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### A function that returns a function" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a):\n", " def g(x):\n", " return a + x\n", " return g" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "g = f(3)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dictionary dispatch" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true }, "outputs": [], "source": [ "funcs = {\n", " 'left' : lambda p: point(p.x - 1, p.y),\n", " 'right': lambda p: point(p.x + 1, p.y),\n", " 'up' : lambda p: point(p.x, p.y + 1),\n", " 'down' : lambda p: point(p.x, p.y - 1),\n", "}" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "moves = ['left', 'left', 'up', 'up', 'down', 'up', 'down', 'right']" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from collections import namedtuple\n", "\n", "point = namedtuple('point', 'x y')" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "robot = point(0, 0)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "robot.x" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "left point(x=-1, y=0)\n", "left point(x=-2, y=0)\n", "up point(x=-2, y=1)\n", "up point(x=-2, y=2)\n", "down point(x=-2, y=1)\n", "up point(x=-2, y=2)\n", "down point(x=-2, y=1)\n", "right point(x=-1, y=1)\n" ] } ], "source": [ "for move in moves:\n", " robot = funcs[move](robot)\n", " print('%-8s %s' % (move, robot))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Map, filter and reduce" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Map" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "map(lambda x: x**2, range(4))" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(map(lambda x: x**2, range(4)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Filter" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "filter(lambda x: x % 2 == 0, range(4))" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 2]" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(filter(lambda x: x % 2 == 0, range(4)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reduce" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from functools import reduce" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(lambda x, y: x + y, range(1, 5))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "110" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(lambda x, y: x + y, range(1, 5), 100)" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6]" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(lambda xs, ys: xs + ys, [[1,2], [3,4], [5,6]])" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 9., 12.])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(lambda xs, ys: xs + ys, [[1,2], [3,4], [5,6]], np.zeros(2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### All together " ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "220" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(lambda a, b: a + b, \n", " map(lambda x: x**2, \n", " filter(lambda x: x % 2==0, range(1, 11))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Equivalent to" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "220" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum([x**2 for x in range(1, 11) if x % 2 == 0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Decorators" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import time" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def timer(f):\n", " def g(*args, **kwargs):\n", " start = time.time()\n", " ans = f(*args, **kwargs)\n", " elapsed = time.time() - start\n", " return(ans, 'Function took %s seconds' % elapsed)\n", " return g" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fib(n):\n", " a, b = 1, 1\n", " for i in range(n):\n", " a, b = b, a + b\n", " return a" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[fib(i) for i in range(11)]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": true }, "outputs": [], "source": [ "timed_fib = timer(fib)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(89, 'Function took 3.0994415283203125e-06 seconds')" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "timed_fib(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Syntactic sugar for defining a decorated function" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": true }, "outputs": [], "source": [ "@timer\n", "def fib(n):\n", " a, b = 1, 1\n", " for i in range(n):\n", " a, b = b, a + b\n", " return a" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(89, 'Function took 3.0994415283203125e-06 seconds')" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fib(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Useful modules for functional programming" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operator\n", "\n", "Avoids use of `lambda` for built-in operators. Often more efficient." ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import operator as op" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "24" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reduce(op.mul, range(1, 5))" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[0, 1, 2, 3, 4],\n", " [1, 2, 3, 4, 5],\n", " [2, 3, 4, 5, 6],\n", " [3, 4, 5, 6, 7],\n", " [4, 5, 6, 7, 8]]" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xxs = [range(i, i+5) for i in range(5)]\n", "list(map(list, xxs))" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.78 µs ± 110 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" ] } ], "source": [ "%timeit -n1000 list(map(op.itemgetter(-1), xxs))" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.97 µs ± 61.7 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" ] } ], "source": [ "%timeit -n1000 list(map(lambda x: x[-1], xxs))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functools" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import functools as fn" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(a, b, c):\n", " return a, b, c\n", "\n", "g = fn.partial(f, c = 3)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 2, 3)" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g(1,2)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def recursive_fib(n):\n", " if n==0 or n==1:\n", " return 1\n", " else:\n", " return recursive_fib(n-1) + recursive_fib(n-2)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[recursive_fib(i) for i in range(11)]" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10946" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "recursive_fib(20)" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5.03 ms ± 46.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "timeit -n 100 recursive_fib(20)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "collapsed": true }, "outputs": [], "source": [ "@fn.lru_cache()\n", "def recursive_fib2(n):\n", " if n==0 or n==1:\n", " return 1\n", " else:\n", " return recursive_fib2(n-1) + recursive_fib2(n-2)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10946" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "recursive_fib2(20)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "150 ns ± 5.62 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "timeit -n 100 recursive_fib2(20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Itertools" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import itertools as it" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Slicing infinite streams" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.islice(it.count(), 10))" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 0, 1, 2, 0, 1, 2, 0]" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.islice(it.cycle(range(3)), 10))" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('a', 'b', 'c', 'd'),\n", " ('a', 'b', 'd', 'c'),\n", " ('a', 'c', 'b', 'd'),\n", " ('a', 'c', 'd', 'b'),\n", " ('a', 'd', 'b', 'c'),\n", " ('a', 'd', 'c', 'b'),\n", " ('b', 'a', 'c', 'd'),\n", " ('b', 'a', 'd', 'c'),\n", " ('b', 'c', 'a', 'd'),\n", " ('b', 'c', 'd', 'a'),\n", " ('b', 'd', 'a', 'c'),\n", " ('b', 'd', 'c', 'a'),\n", " ('c', 'a', 'b', 'd'),\n", " ('c', 'a', 'd', 'b'),\n", " ('c', 'b', 'a', 'd'),\n", " ('c', 'b', 'd', 'a'),\n", " ('c', 'd', 'a', 'b'),\n", " ('c', 'd', 'b', 'a'),\n", " ('d', 'a', 'b', 'c'),\n", " ('d', 'a', 'c', 'b'),\n", " ('d', 'b', 'a', 'c'),\n", " ('d', 'b', 'c', 'a'),\n", " ('d', 'c', 'a', 'b'),\n", " ('d', 'c', 'b', 'a')]" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.permutations('abcd'))" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('a', 'b', 'c'), ('a', 'b', 'd'), ('a', 'c', 'd'), ('b', 'c', 'd')]" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.combinations('abcd', 3))" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['abc', 'abd', 'acd', 'bcd']" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[''.join(s) for s in it.combinations('abcd', 3)]" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.takewhile(lambda x: x < 20, it.count(10)))" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[range(0, 5), range(1, 6), range(2, 7), range(3, 8), range(4, 9)]" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "xxs" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6]" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.chain([1,2], [3,4], [5,6]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## [Toolz](http://toolz.readthedocs.io/en/stable/)\n", "\n", "This is not part of the standard library but very useful." ] }, { "cell_type": "code", "execution_count": 80, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import toolz as tz" ] }, { "cell_type": "code", "execution_count": 141, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import toolz.curried as tzc" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1, 2),\n", " (1, 2, 3),\n", " (2, 3, 4),\n", " (3, 4, 5),\n", " (4, 5, 6),\n", " (5, 6, 7),\n", " (6, 7, 8),\n", " (7, 8, 9)]" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.sliding_window(3, range(10)))" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'d': 2, 'e': 3, 'l': 1, 'm': 1, 't': 1, 'u': 1, 'w': 1}" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tz.frequencies('tweedledum')" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cumsum = fn.partial(tz.accumulate, op.add)\n", "list(cumsum(range(10)))" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['a', 0, 'x', 'b', 1, 'y', 'c', 2, 'z']" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.interleave(['abc', range(3), 'xyz']))" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['a', '-', 'b', '-', 'c']" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.interpose('-', 'abc'))" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1, 2), (3, 4, 5), (6, 7, 8)]" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.partition(3, range(10)))" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 'None', 'None')]" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.partition(3, range(10), pad='None'))" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9,)]" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.partition_all(3, range(10)))" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['t', 'w', 'e', 'd', 'l', 'u', 'm']" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(tz.unique('tweedledum'))" ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "collapsed": true }, "outputs": [], "source": [ "fruits = ['apple', 'banana', 'orange', 'pear', 'kiwi', 'apricot']" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{4: ['pear', 'kiwi'], 5: ['apple'], 6: ['banana', 'orange'], 7: ['apricot']}" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tz.groupby(len, fruits)" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': ['apple', 'apricot'],\n", " 'b': ['banana'],\n", " 'k': ['kiwi'],\n", " 'o': ['orange'],\n", " 'p': ['pear']}" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tz.groupby(lambda s: s[0], fruits)" ] }, { "cell_type": "code", "execution_count": 94, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import faker" ] }, { "cell_type": "code", "execution_count": 95, "metadata": { "collapsed": true }, "outputs": [], "source": [ "fake = faker.Faker()" ] }, { "cell_type": "code", "execution_count": 129, "metadata": { "collapsed": true }, "outputs": [], "source": [ "addresses = [fake.address() for i in range(1000)]" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['97134 Butler Oval\\nAguilarberg, IN 46709-3849',\n", " '154 Lisa Point Apt. 774\\nRobertbury, UT 49310',\n", " '54122 Madeline Knolls\\nJessicaton, WV 22146',\n", " '68583 Bradley Throughway Apt. 916\\nLake Davidville, WI 11324-0572',\n", " 'Unit 6904 Box 5565\\nDPO AE 63827',\n", " '5109 Brenda Hills Suite 001\\nSolishaven, KY 95727-8993',\n", " '15848 Dawson Ports\\nWest Jeffstad, PA 33793',\n", " '91291 Angela Valleys Apt. 434\\nNorth Debbieville, PR 47717-7165',\n", " '149 Katherine Skyway Suite 676\\nMarkchester, TX 64457-9707',\n", " '962 Leonard Row Suite 027\\nJodiside, TN 19605']" ] }, "execution_count": 130, "metadata": {}, "output_type": "execute_result" } ], "source": [ "addresses[:10]" ] }, { "cell_type": "code", "execution_count": 131, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def get_state(s):\n", " return s.split(',')[-1].strip()[:2]" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['IN', 'UT', 'WV', 'WI', 'Un', 'KY', 'PA', 'PR', 'TX', 'TN']" ] }, "execution_count": 132, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[get_state(address) for address in addresses][:10]" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['00509 Watson View Suite 948\\nJoshuaburgh, NC 50750',\n", " '80032 Kim Summit Suite 826\\nLake Patrickmouth, NC 13150',\n", " '891 Randall Mount Suite 207\\nSouth Sergio, NC 31915',\n", " '78427 Fuller Estate\\nLake Loritown, NC 47978',\n", " '1843 Richard Freeway\\nMckayfurt, NC 06130-7973',\n", " '2963 Smith Pine\\nPort Dustin, NC 25495',\n", " '590 Pamela Mews\\nNew Brandon, NC 43544',\n", " '1085 Brianna Locks\\nRossbury, NC 87652-3315',\n", " '5791 Nelson Street Apt. 471\\nLake Sarafort, NC 93405-2390',\n", " '5888 Brad Run Suite 087\\nGarretthaven, NC 37155',\n", " '0553 Candice Ridge Apt. 505\\nBakerville, NC 19344',\n", " '9294 Andrew Hollow\\nSnydertown, NC 26055-8332',\n", " '9470 Elizabeth Stream\\nHeidiburgh, NC 87725-4062',\n", " '21597 Lane Island\\nMarcstad, NC 75752']" ] }, "execution_count": 133, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tz.groupby(get_state, addresses).get('NC')" ] }, { "cell_type": "code", "execution_count": 134, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from math import sqrt" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[100,\n", " 10.0,\n", " 3.1622776601683795,\n", " 1.7782794100389228,\n", " 1.333521432163324,\n", " 1.1547819846894583,\n", " 1.0746078283213176,\n", " 1.036632928437698,\n", " 1.018151721718182,\n", " 1.0090350448414476]" ] }, "execution_count": 139, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(it.islice(tz.iterate(sqrt, 100), 10))" ] }, { "cell_type": "code", "execution_count": 146, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(5, 6, 7, 8, 9)" ] }, "execution_count": 146, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tz.pipe(range(10),\n", " tzc.take(10), \n", " tzc.tail(5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### [Funcy](https://funcy.readthedocs.io/en/stable/index.html)\n", "\n", "This is very similar to `toolz`. You can use either one, or even both together with `itertools` and `functools`." ] }, { "cell_type": "code", "execution_count": 150, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import funcy" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(funcy.flatten([[[1,[2,3]]], [4,5], [6,[7,[8,9],[10],11]]]))" ] }, { "cell_type": "code", "execution_count": 166, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "['97134 Butler Oval',\n", " 'Aguilarberg, IN 46709-3849',\n", " '154 Lisa Point Apt. 774',\n", " 'Robertbury, UT 49310',\n", " '54122 Madeline Knolls']" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "funcy.take(5, funcy.mapcat(str.splitlines, addresses))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }