I'm revisiting some scheme excercises in python (if that makes sense) to find out what python can do in terms of FP. My problem concerns lambda in python : Can i define a general function in python with an operator as one of the arguments?
Think this :
def f (op,x,y):
#return some lambda function that combines x and y in the appropriate way
#i.e if op is +, then return x+y, if op is -, then return x-y etc
#Edit : added usage
#this should be called like this:
f(+, 1,2) #should return 3
I know this is possible in scheme, but is there something equivalent in python? I've gotten the impression that lambda in python is just a shorter way of defining a method, and I've not found any way to define a general combiner function in python.
I can see some points in your question, lets go through them in order:
Yes:
def f(op, x, y):
return op(x, y)
def add(x, y):
return x + y
f(add, 10, 7) #gives 17
Unlike scheme, Python operators are not functions so you can't pass them directly as parameters. You can either create the wrapper functions yourself or you can import the operator module from the standard library.
import operator
operator.add(1, 2)
(lambda x,y : x+y)(1, 2)
Operators not being real functions is a little sad in most cases but at least Python gives us chained comparisons like 10 <= x < 100
in exchange...
In the general sense, functions in Python are as powerful as functions in Scheme, however there are some things to note:
The lambda keyword is limited
You can only have a single expression as the function body
f = lambda x, y: x + y
Since there are a bunch of things in Python that are statements and not expressions (assignments, the 2.x print
, ...), you often need to fall back to named functions instead.
There are closures
def make_printer(msg):
def printer():
print msg
return printer
printer('a message')()
But mutating variables in them is a pain
This doesn't work. It tries to bind a new n for the inner function instead of using the outer one
def make_counter(n):
def inc():
n = n + 1
return n
return inc
new 3.x nonlocal keyword
def make_counter(n):
def inc():
nonlocal n
n = n + 1
return n
return inc
workaround w/ mutable objects
def make_counter(n):
nw = [n]
def inc():
nw[0] = nw[0] + 1
return nw[0]
return inc
Objects instead of closures. Uses the magic __call__
method to pretend its a function
class Counter:
def __init__(self, n):
self.n = n
def __call__(self):
self.n += 1
return self.n
Operators aren't really function in python, more like methods -- x + y
is short for x.__add__(y)
, or y.__radd__(x)
. You can use the functions in the operator
module to emulate the behavior you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With