introduction to higher order (functional programming) (python) - map... · introduction to higher...

77
Introduction to Higher Order (Functional Programming) (Python) John R. Woodward

Upload: others

Post on 21-Aug-2020

29 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Introduction to Higher Order (Functional Programming) (Python)

John R. Woodward

Page 2: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Can Your Programming Language Do This? Motivating Example

• http://www.joelonsoftware.com/items/2006/08/01.html

You only need to write code for the “bit that changes”

Page 3: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What is repeated here? What is the abstraction?

Page 4: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

The Abstraction

• We are

• - getting an “object” (lobster/chicken)

• - repeating an action twice

– Put in pot, put in pot

– Boom boom, boom boom.

• The first action is with the object.

• The second action is with another object (water, coconut)

Page 5: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

We repeat the 2nd action TWICE

Page 6: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Higher Order Functions (HOF)

1. In most programming languages we pass around integers, Booleans, strings, as argument to function and return types

2. For example Boolean isPrime(Integer n)

3. Takes as input an integer and returns output true/false depending on if it is prime or not.

4. With functional languages we can pass around functions. Type signatures

Page 7: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Higher Order Function

• A higher order function is a function which

• - take another function as input

Or

• Returns a function as output.

Page 8: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Examples of higher order functions

1. At college you had to differentiate y=mx+c

2. Also integration (returns a function).

3. In physics…law of refraction/reflection.

4. Fermat's principle states that light takes a path that (locally) minimizes the optical length between its endpoints. (Lagrangian Mechanics)

5. Mechanics…hanging chain (a ball rolls down a slope – a chain takes on a shape).

6. Droplets minimize surface area, aerodynamics (wing shape).

7. CALCULUS OF VARIATION

Page 9: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Example: A linear function

def linear(gradient, intercept):

def result(x):

return gradient*x + intercept

return result #not result(x)

myLinearFunction = linear(4,3)

#makes a function 4*x+3

print myLinearFunction(8)

#evaluate the function at point 8

print linear(4,3)(8)

#or do directly

Page 10: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

f(x) and f

1. In maths f and f(x) are different.

2. f is a function!

3.f(x) is the value of f at value x

4. Never say “the function f(x)”

5.Say - The function f that takes a variable x (i.e. f takes var x)

6. Or – the function f at the point x (i.e. f given x has the value ??)

Page 11: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Inputs, outputs and functions

• Input x, to a function f, outputs f(x)

• f is a “process”

1. x=5,

2. f(x) = x+2,

3. f(5)=7 5 7

f

• Typically inputs/outputs are basic data types (int, float, double, Boolean, char, String)

Page 12: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Maximum of two numbers def max(x,y):

if (x>y):

return x

else:

return y

#what is the input and output data-type

e.g. max(2,5)=???

2

5

?

Page 13: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Maximum of two functions def maxVal(f, g, x):

return max(f(x), g(x))

#what is the input and output data-type

example

def f1(x): return x+2

def f2(x): return 6

maxVal(f1,f2,3)=?

f2

f1

3

?

maxVal

Page 14: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Returning the Function

def maxFun(f, g):

def maximumFunction(x):

return max(f(x), g(x))

return maximumFunction

def f1(x): return x+2

def f2(x): return 6

maxFun(f1,f2)=?

f1

f2

?

maxFun

Page 15: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Returning the Function

def maxFun(f, g):

def maximumFunction(x):

return max(f(x), g(x))

return maximumFunction

def f1(x): return x+2

def f2(x): return 6

maxFun(f1,f2)=?

f1

f2

?

maxFun

Page 16: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Summation 1/2

Could you write this code for f(x) = 2x ???

How could you write this code for f(x) in general ???

1. In maths (a little like a for loop) 𝑓(𝑖) = 𝑓(1) + 𝑓(2) + ⋯+ 𝑓(10)𝑖=10𝑖=1

2. ∑ takes 3 arguments, and upper and lower bound and a function to sum over.

3. E.g. 2 ∗ 𝑖𝑖=10𝑖=1 = 2 + 4 +⋯+ 20 =

Page 17: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Summation 2/2

1. In maths 𝑓(𝑖) = 𝑓(1) + 𝑓(2) + ⋯+ 𝑓(10)𝑖=10𝑖=1

2. ∑ takes 3 arguments, and upper and lower bound and a function to sum over.

3. E.g. 2 ∗ 𝑖𝑖=10𝑖=1 = 2 + 4 +⋯+ 20 =

def sum(f, a, b):

total = 0

for i in range(a, b+1):

total += f(i)

return total

Page 18: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Product Symbol in Maths

1. In mathematics we often use the product

symbol . 𝑓(𝑖)𝑖=3𝑖=1 means f(1)*f(2)*f(3).

2. You can do this for the labs

3. Hint: is its almost “cut and paste”, but you need to think a little.

Page 19: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Your turn…in the lab

1. Write a function f which returns a function which is the minimum of functions f1, f2

2. i.e. f(x)=min {f1(x) and f2(x)}

3. Write a function which returns a function which is the average of two functions

4. i.e. f(x) = {f1(x) + f2(x)}/2

5. Can you generalize this to a list of functions?

Page 20: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

1 Simple example: Higher order Function

• #Takes a function f and value x and evaluates f(x), returning the result.

def apply(f, x):

return f(x)

• #f is a function, x is input to f

Page 21: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

2 Composition as HOF

def compositionValue(f, g, x):

return f(g(x))

1. This take two functions f and g.

2. And a value x

3. And calculates the values f(g(x))

4. What restrictions are there?

f

g

x

f(g(x))

g(x)

Page 22: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

3 Returning a Function fg def compositionFunction(f, g): def result(x): return f(g(x)) return result • myFunction = compositionFunction(timesThree, timesTwo)

• print myFunction(4) • print apply(compositionFunction(timesThree, timesTwo) , 4)

• print (lambda x, y :compositionFunction(x,y)) (timesThree, timesTwo) (4)

Page 23: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Variable as Strings, and “literal strings”

name = "john"

print name

#Or we can just print the name directly

print "john"

1. If we only use “John” once – we could use a string literal (a one-off use).

2. If we use “John” multiple times – define a variable – name – and use that.

Page 24: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Anonymous Functions (lambda)

def f (x): return x**2

print f(8)

#Or we can do

g = lambda x: x**2

print g(8)

#Or just do it directly

print (lambda x: x+2) (4)

y = (lambda x: x*2) (4)

print y # the value is stored in y

Page 25: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What do the following print

def inc(x): return x+1

1. print inc(5) 2. print type(inc) 3. print type(inc(5)) 4. print type("inc(5)") 5. print type(eval ("inc(5)" )) 6. print type((lambda x: x*2)) 7. print type((lambda x: x*2) (4))

Page 26: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

And the types are…

1. 6

2. <type 'function'>

3. <type 'int'>

4. <type 'str'>

5. <type 'int'>

6. <type 'function'>

7. <type 'int'>

Page 27: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What does the following do 1

def f(a, b): return a+b

def inc(x): return x+1

def double(x): return x*2

Page 28: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What does the following do 2

def f(a, b): return a+b

def inc(x): return x+1

def double(x): return x*2

1. print f(1,2)

2. print f("cat","dog")

3. print f(inc, double)

Page 29: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

1. 3 2. catdog 3. Traceback (most recent call last): File "C:\Users\jrw\workspace\Python1\addition1.py", line 6, in <module> • print f(inc, double) • File

"C:\Users\jrw\workspace\Python1\addition1.py", line 1, in f

• def f(a, b): return a+b • TypeError: unsupported operand type(s) for +:

'function' and 'function'

Page 30: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What does the following print

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]

1. print filter(lambda x: x % 3 == 0, foo)

2. print map(lambda x: x * 2 + 10, foo)

3. print reduce(lambda x, y: x + y, foo)

Page 31: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

1. [18, 9, 24, 12, 27]

2. [14, 46, 28, 54, 44, 58, 26, 34, 64]

3. 139

Page 32: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

What does the following print

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]

1. print type(filter(lambda x: x % 3 == 0, foo))

2. print type(map(lambda x: x * 2 + 10, foo))

3. print type(reduce(lambda x, y: x + y, foo))

Page 33: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

1. <type 'list'>

2. <type 'list'>

3. <type 'int'>

Page 34: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Lambda – filter, map, reduce

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]

print filter(lambda x: x % 3 == 0, foo)

#[18, 9, 24, 12, 27]

print map(lambda x: x * 2 + 10, foo)

#[14, 46, 28, 54, 44, 58, 26, 34, 64]

print reduce(lambda x, y: x + y, foo)

#139

#(more detail in a few slides)

Page 35: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Lists

• Functional programming uses LISTs as its primary data structure. E.g. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

• listNumbers = [1,2,3] #[1,2,3]

• listNumbers.append(4)#[1, 2, 3, 4]

• listNumbers.insert(2, 55)#[1, 2, 55, 3, 4]

• listNumbers.remove(55)#[1, 2, 3, 4]

• listNumbers.index(4)#3

• listNumbers.count(2)#1

Page 36: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Map – (a transformation)

• Map takes a function and a list and applies the function to each elements in the list

• def cube(x): return x*x*x

• print map(cube, range(1, 11))

• print map(lambda x :x*x*x, range(1, 11))

• print map(lambda x :x*x*x, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

• # [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

• #what is the type signature

Page 37: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

filter

• Filter takes a function (what type???) and a list, and returns items which pass the test

• def f1(x): return x % 2 != 0

• def f2(x): return x % 3 != 0

• def f3(x): return x % 2 != 0 and x % 3 != 0

1. print filter(f1, range(2, 25))

2. print filter(f2, range(2, 25))

3. print filter(f3, range(2, 25))

Page 38: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

filter 2

• def f1(x): return x % 2 != 0 • def f2(x): return x % 3 != 0 • def f3(x): return x % 2 != 0 and x % 3 != 0

• print filter(f1, range(2, 25)) • # [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23]#odd • print filter(f2, range(2, 25)) • # [2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23] • #not divisible by 3 • print filter(f3, range(2, 25)) • # [5, 7, 11, 13, 17, 19, 23]#not divisiable by 2 and 3

Page 39: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

A list can contain different datatypes

• list1 = [0, 1, 0.0, 1.0, True, False, "True", "False", "", None, [True], [False]]

• def isTrue(x):

• return x

• print filter(isTrue, list1)

Page 40: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

• [1, 1.0, True, 'True', 'False', [True], [False]]

• list1 = [0, 1, 0.0, 1.0, True, False, "True", "False", "", None, [True], [False]]

Page 41: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Reduce – try this

• reduce( (lambda x, y: x + y), [1,2,3,4] )

• reduce( (lambda x, y: x - y), [1,2,3,4] )

• reduce( (lambda x, y: x * y), [1,2,3,4] )

• reduce( (lambda x, y: x / y), [1,2,3,4] )

Page 42: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

answers

• reduce( (lambda x, y: x + y), [1, 2, 3, 4] ) • reduce( (lambda x, y: x - y), [1, 2, 3, 4] ) • reduce( (lambda x, y: x * y), [1, 2, 3, 4] ) • reduce( (lambda x, y: x / y), [1, 2, 3, 4] ) • 10 • -8 • 24 • 0

Page 43: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

The last one

• print reduce( (lambda x, y: x / y), [1.0, 2.0, 3.0, 4.0] )

• ??? answer

Page 44: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

The last one

• print reduce( (lambda x, y: x / y), [1.0, 2.0, 3.0, 4.0] )

• 0.0416666666667

• # what is the type signature?

Page 45: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Map, Reduce, Filter

1. Map, reduce and filter all take a function as an argument.

2. What type is the function in each case

3. Map,

4. Reduce,

5. Filter

Page 46: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Data Types of Function Taken.

1. Map: takes an argument of type T and returns a type S. It returns a list of S, denoted [S]

2. Reduce: takes two arguments of type T, and returns an argument of type T

3. Filter: take an argument of type T and returns a Boolean (True/False). It returns a list of T, denoted [T]

Page 47: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Partial Application

1. Motivating example

2. Addition (+) takes two arguments

3. (arg1 + arg2)

4. What if we only supply one argument?

5. We cannot compute e.g. (1+)

6. But it is still a function of one argument

7. (1+ could be called what???)

Page 48: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Visualization

ADD

3

2 1

ADD

3

??? 1

This is how we normally think of the add function

Page 49: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Inc as partial add

• #add (2 args), inc(x)=add(1,x)

• #inc is a special case of add

• from functools import partial

• def add(a,b):

• return a+b

• inc = partial(add, 1)

• print inc(4)

Page 50: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Inc defined with add

• #add takes 2 arguments

• def add(x,y):

• return x+y

• #we can define a new function by hardcoding one variable

• def inc(x):

• return add(1,x)

• print inc(88)

Page 51: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

double as partial mul

• #mul(2 args), double(x)=mul(2,x)

• #double is a special case of mul

• from functools import partial

• def mul(a,b):

• return a*b

• double = partial(mul, 2)

• print double(10)

Page 52: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Functions as special cases

• #square and cube are special cases of the power function

• def power(base, exponent):

• return base ** exponent

• def square(base):

• return power(base, 2)

• def cube(base):

• return power(base, 3)

Page 53: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Equivalent Code

• from functools import partial

• square = partial(power, exponent=2)

• cube = partial(power, exponent=3)

Page 54: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

referential transparency

1. Haskell is a pure functional language referential transparency - the evaluation of an expression does not depend on context.

2. The value of an expression can be evaluated in any order (all sequences that terminate return the same value) (1+2)+(3+4) we could reduce this in any order.

3. In the 2nd world war, Richard Feynman was in charge of making calculation for the atomic bomb project.

4. These calculations were done by humans working in parallel. e.g. calculate exponential

Page 55: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Functional Programming

1. Programming paradigm? Object oriented, imperative

2. Immutable state (referential transparency)

3. Higher order functions, partial functions, anonymous functions (lambda)

4. Map, filter, reduce (fold)

5. List data structures and recursion feature heavily

6. Type inference (type signatures)

7. Lazy and eager evaluation, list comprehension

Page 56: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

State & Referential Transparency

1. In maths, a function depends ONLY ON ITS INPUTS e.g. root(4) = +/-2

2. This is a “stateless function” 3. A stateful function (method, procedure) stores some

data which changes i.e. mutable data 4. E.g. a “function” which returns the last argument it

was given 5. F(4) = -1, F(55) = 4, F(3) = 55, F(65) = 55, 6. (side effects, e.g. accessing a file) 7. Harder to debug stateful function than stateless

(why).

Page 57: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

List Comprehensions

• List comprehensions provide a concise way to create lists.

• To make new lists, where each element is the result of some operation applied to each member of another sequence.

Page 58: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

List Comprehensions

• The following are common ways to describe lists (or sets, or tuples, or vectors) in mathematics.

S = {x² : x in {0 ... 9}} V = (1, 2, 4, 8, ..., 2¹²) M = {x | x in S and x even}

Page 59: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Create a list of squares

For example, assume we want to create a

list of squares, like:

• squares = []

• for x in range(10):

• squares.append(x**2)

• print squares

• #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Page 60: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

As a list comprehension

We can obtain the same result with:

• squares = [x**2 for x in range(10)]

This is also equivalent to

• squares = map(lambda x: x**2, range(10)),

However the list comprehension is more

concise and readable.

(choose the way that works for you, but do try different techniques)

Page 61: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

In Python

• S = [x**2 for x in range(10)]

• V = [2**i for i in range(13)]

• M = [x for x in S if x % 2 == 0]

• print S;

• print V;

• print M

Page 62: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

In Python

• S = [x**2 for x in range(10)]

• V = [2**i for i in range(13)]

• M = [x for x in S if x % 2 == 0]

• print S;

• print V;

• print M

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096] [0, 4, 16, 36, 64]

Page 63: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Calculating Primes

1. We can calculate the primes by

2. first build a list of non-prime numbers,

3. then use another list comprehension to get the "inverse" of the list,

Page 64: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Calculating Primes

noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]

print noprimes

primes = [x for x in range(2, 50) if x not in noprimes]

print primes

Page 65: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

• noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]

• print noprimes • #[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,

30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 10, 15, 20, 25, 30, 35, 40, 45, 12, 18, 24, 30, 36, 42, 48, 14, 21, 28, 35, 42, 49]

• primes = [x for x in range(2, 50) if x not in noprimes]

• print primes • #[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,

43, 47]

Page 66: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Nested List Comprehensions

1. You can nest list comprehensions (just like you can do with other python commands).

2. In this case just substitute the “noprimes” variable with the python code.

3. I would not recommend this, as it is harder to read

4. It is also harder to debug (where would you insert a print statement)

Page 67: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Nested List Comprehensions

• primes = [x for x in range(2, 50) if x not in [j for i in range(2, 8) for j in range(i*2, 50, i)]]

• print primes

• #[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Page 68: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

List Comprehension with Strings

words = 'The quick brown fox jumps over the lazy dog'.split()

print words

stuff = [[w.upper(), w.lower(), len(w)] for w in words]

for i in stuff:

print i

Page 69: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

List Comprehension with Strings

words = 'The quick brown fox jumps over the lazy dog'.split()

print words

stuff = [[w.upper(), w.lower(), len(w)] for w in words]

for i in stuff:

print i

['THE', 'the', 3] ['QUICK', 'quick', 5] ['BROWN', 'brown', 5] ['FOX', 'fox', 3] ['JUMPS', 'jumps', 5] ['OVER', 'over', 4] ['THE', 'the', 3] ['LAZY', 'lazy', 4] ['DOG', 'dog', 3]

Page 70: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Output 2

• words = 'The quick brown fox jumps over the lazy dog'.split()

• stuff = [[w.upper(), w.lower(), len(w)] for w in words]

• for i in stuff:

• print i

• print type(words)

• print type(stuff)

<type 'list'> <type 'list'>

Page 71: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

3 EXAMPLES

print [y for y in [3,1,4]]

print [(x, y) for x in [1,2,3] for y in [3,1,4]]

print [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

OUTPUT

• [3, 1, 4]

• [(1, 3), (1, 1), (1, 4), (2, 3), (2, 1), (2, 4), (3, 3), (3, 1), (3, 4)]

• [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Page 72: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Written as nested for loops

• [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]

Is equivalent to

• combs = []

• for x in [1,2,3]:

• for y in [3,1,4]:

• if x != y:

• combs.append((x, y))

the order of the for and if statements is the same in both

(choose the way that works for you, but do try different techniques)

Page 73: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

More examples

vec = [-4, -2, 0, 2, 4]

1. print [x*2 for x in vec]

2. print [x for x in vec if x >= 0]

3. print [abs(x) for x in vec]

• fruits = [' banana', ' loganberry ', 'passion fruit ']

4. print [fruit.strip() for fruit in fruits]

5. print [(x, x**2) for x in range(6)]

Page 74: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

• [-8, -4, 0, 4, 8]

• [0, 2, 4]

• [4, 2, 0, 2, 4]

• ['banana', 'loganberry', 'passion fruit']

• [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]

Page 75: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

examples

matrix = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12],] print [row[i] for row in matrix for i in range(4)] print [[row[i]] for row in matrix for i in range(4)] print [[row[i] for row in matrix] for i in range(4)]

Page 76: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

output

• [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

• [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]]

• [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

Page 77: Introduction to Higher Order (Functional Programming) (Python) - map... · Introduction to Higher Order (Functional Programming) (Python) ... In most programming languages we pass

Equivalent to …

transposed = []

for i in range(4):

# the following 3 lines implement the nested listcomp

transposed_row = []

for row in matrix:

transposed_row.append(row[i])

transposed.append(transposed_row)