Fun with funS
Functional programming in Python
Paweł Pamuła
Overview
- Why do we bother?
- Is Python a functional language?
- Does Python have functional features?
- Let's see how do they work!
Programming paradigms
- Imperative programming
First do this and next do that
- Object-oriented programming
Think in terms of objects
- Functional programming
Evaluate an expression and use the resulting value for something
- Logic, aspect-oriented, reactive programming...
Functional Concepts
- First class & higher-order functions
Referential transparency (pure functions)
- Immutable data
- Lazy evaluation
- Recursion
- ...
Advantages of functional approach
- Describe what you want, not how to get it
- Concise code
- Modularity
- Clarity
- New perspective!
- and that is only my opinion :)
Python does not promote functional approach!
I have never considered Python to be heavily influenced by functional languages, no matter what people say or think.
However, earlier on, it was clear that users wanted to do much more with lists and functions.
Functional features in python
- functions as first-class objects
- lambdas
- lazy evaluation
- map, filter, reduce
- functools & itertools
First class objects
>>> def forall(fun, val):
... output = []
... for v in val:
... output.append(fun(v))
... return output
...
>>> def double(x):
... return 2*x
...
>>> forall(double, [1, 2, 3, 4])
[2, 4, 6, 8]
LAMBDA FUNCTIONS
- one-line anonymous functions
- expression, not a statement
- single expression, not a block of statements
>>> reverse = lambda s: s[::-1]
>>> reverse('abc')
'cba'
>>> forall(lambda s: s[::-1], ['abc', 'kajak'])
['cba', 'kajak']
- strongly connected with map, reduce, filter use
Currying
>>> def log(level, message):
... print "[%s] %s" % (level, message)
...
>>> log("error", "It's gonna explode!")
[error] It's gonna explode!
CURRYING
from functools import partial
def log(level, message):
print "[%s] %s" % (level, message)
levels = ['info', 'warning', 'error', 'debug']
funs = dict((item, partial(log, item)) for item in levels)
funs['info']("That's a very important information")
print funs
[info] That's a very important information
Lazy evaluation
- Evaluation strategy which delays the evaluation of an expression until its value is needed
- Enables construction of potentially infinite structures
- Increases performance
lazy evaluation
- Python does not use lazy evaluation
- Even though
>>> 1 or 1/0
1
- This one takes 3 seconds
>>> import time
>>> print ['some text', time.sleep(3)][0]
- Most common example: superiority of xrange over range
-
(only in Python 2.#)
MAP
- Function map takes function and collection as a parameter
- Applies function to every element
import os
files = ['file1.pdf', 'file2.txt']
filename = lambda f: os.path.splitext(f)[0]
modules = map(filename, files)
['file1', 'file2']
MAP & CURRYING
Sum of integers
def isum(a, b):
return sum(range(a, b+1))
Sum of squares
def ssum(a, b):
return sum(map(lambda x: x**2, range(a, b+1)))
Sum of roots
import mathdef rsum(a, b):
return sum(map(lambda x: math.sqrt(x), range(a, b+1)))
MAP & CURRYING
import math
def general_sum(f):
def inner(a, b):
return sum(map(f, range(a, b+1)))
#returns function!
return inner
log_sum = general_sum(math.log)print log_sum(1, 10), ' should be more or less equal to ', math.log(reduce(lambda x, y: x*y, range(1, 11)))
15.1044125731 should be more or less equal to 15.1044125731
REDUCE
- Retrieves data from the sequence
- Outputs a single value
- If sequence s has one element -> returns s[0]
- If sequence s has two elements -> returns f(s[0], s[1])
- In case of three elements -> f(f(s[0], s[1]), s[2])
- And so on...
reduce
>>> f = lambda a,b: "f(%s,%s)" % (a,b)
>>> reduce(f, '1234')
f(f(f(1,2),3),4)
REDUCE, ANOTHER EXAMPLE
>>> mul = lambda x, y: 10*x + y
>>> reduce(mul, [1, 4, 1, 0])
1410
ANOTHER REDUCE EXAMPLE
def gcd(a, b):
while b:
a, b = b, a % b
return a
def lcm(a, b):
return a * b // gcd(a, b)
def lcmm(*args):
return reduce(lcm, args)
print lcmm(10, 17, 4)
LAST BUT NOT LEAST: FILTER
- Accepts function & iterable as an argument
- Returns (filtered) list
- Example is superfluous :)
BONUS QUESTION
How are parameters passed to function in Python?
def f(x):
x[0] = 10
def g(x):
x = [4, 5, 6, 7]
def h(some_string):
some_string = 'New string'
x = [0, 1, 2, 3]
f(x)
h(x)
s = 'Some string'
h(s)
Next part of the presentation(?)
- higher-order functions
- functools, itertools
- closures
- decorators
- ...
Thank you for your attention!
Paweł Pamuła
pawel.pamula@gmail.com
@github: PawelPamula
Fun with funs
By achr
Fun with funs
Functional aspects of programming in python
- 228