Reputation: 13738
Nowadays, I am starting to learn haskell, and while I do it, I try to implement some of the ideas I have learned from it in Python. But, I found this one challenging. You can write a function in Haskell, that takes another function as argument, and returns the same function with it's arguments' order flipped. Can one do similiar thing in Python? For example,
def divide(a,b):
return a / b
new_divide = flip(divide)
# new_divide is now a function that returns second argument divided by first argument
Can you possibly do this in Python?
Upvotes: 15
Views: 17271
Reputation: 214949
In a pure functional style:
flip = lambda f: lambda *a: f(*reversed(a))
def divide(a, b):
return a / b
print flip(divide)(3.0, 1.0)
A bit more interesting example:
unreplace = lambda s: flip(s.replace)
replacements = ['abc', 'XYZ']
a = 'abc123'
b = a.replace(*replacements)
print b
print unreplace(b)(*replacements) # or just flip(b.replace)(*replacements)
Upvotes: 18
Reputation: 226256
You can create a closure in Python using nested function definitions. This lets you create a new function that reverses the argument order and then calls the original function:
>>> from functools import wraps
>>> def flip(func):
'Create a new function from the original with the arguments reversed'
@wraps(func)
def newfunc(*args):
return func(*args[::-1])
return newfunc
>>> def divide(a, b):
return a / b
>>> new_divide = flip(divide)
>>> new_divide(30.0, 10.0)
0.3333333333333333
Upvotes: 27