Let's say I have an procedural code in python like this,
x = np.random.randint(0, 9, (4,4))
def foo(x):
y = np.rot90(x)
y = np.rot90(y)
return y
# This can be written as
y = rot90(rot90(x))
The above foo function can be written as a composition of functions as all the functions take single argument and returns the single argument.
Consider the another foo function as below which is bit complicated than the previous where all the arity of the functions are not same upon applying the functions
def swap_a_with_b(x, a, b):
x[x==b] = 100
x[x==a] = b
x[x==100] = a
return x
def foo(x):
a, b = np.argsort(np.bincount(x.flatten()))[-2:]
return swap_a_with_b(x, a, b)
how can I write the function foo in the form of composition of functions, where primitive function can be any numpy functions and swap_a_with_b, I can use all the primitive functions, extra helper function swap_a_with_b and any anonymous lambda function.
I know it can be done if we use functools.partial to define a specific function for the specific values of a and b for the higher order function swap_a_with_b, but can we do this as just a function composition with lambda ?
Related
During a tutorial I stumbled upon the following example.
I get the general purpose and mechanism of functions. They get parameters such as "a", "b" and "c" (example below).
But how come that we can "link" the function to an object f that itself can contain 0 as parameters that will then be computed by our lambda expression?
def build_quadratic_function(a,b,c):
return lambda x: a*x**2 + b*x+c
f = build_quadratic_function(2,3,-5)
f(0)
yields:
-5
In layman words, how does the function "know" that 0 must be read by the lambda expression that is contained in the function?
Can somebody explain the mechanism behind it?
Thank you!
def build_quadratic_function(a,b,c):
return lambda x: a*x**2 + b*x + c
is (in all important aspects) equivalent to
def build_quadratic_function(a,b,c):
def func(x):
return a*x**2 + b*x + c
return func
In both cases, the inner function, be it an anonymous one or not, is holding onto the variables in the enclosing scope. You have discovered so called closures.
>>> import inspect
>>> f = build_quadratic_function(2, 3, -5)
>>> inspect.getclosurevars(f)
ClosureVars(nonlocals={'a': 2, 'b': 3, 'c': -5}, globals={}, builtins={}, unbound=set())
A very similar example can be found in the documentation.
Lambdas are small anonymous functions. They can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope.
Therefore if you define a custom function that contains a lambda, and then fix its parameters, it's essentially the same as defining a lambda function and then passing the expression.
For the sake of your example:
def build_quadratic_function(a,b,c):
return lambda x: a*x**2 + b*x+c
f = build_quadratic_function(2,3,-5)
Would create the same output as:
f = lambda x: 2*x**2 + 3*x - 5
In either case, when you call f(0) then the expression gets evaluated with value 0 returning -5.
2*0**2 + 3*0 - 5 = - 5
The improvement using a custom function over the simple definition of the lambda itself is you can modify the a, b and c parameters.
This isn't a lambda specific thing. Its a "closure" and can be done with a regular function also. In fact, a lambda is just an anonymous function. Its it restricted to implementing an expression instead of full python statements, but that's only the case because of python parsing issues. So, this is the same thing
def build_quadratic_function(a,b,c):
def inner(x):
return a*x**2 + b*x+c
return inner
inner uses variables from the enclosing function. When build_quadratic_function returns inner, the current objects in a, b and c are bound to inner. Later, when inner(someval) is called, those bound objects to a, b and c are used. x, which is a parameter to inner needs to be supplied on each call.
You can get the inner function once and use it many times with the same values.
func = build_quadratic_function(1,2,3)
for i in range(10):
print(func(i))
A lambda function is a small anonymous function. (function with no name)
f = build_quadratic_function(2,3,-5)
Till this point, f is equal to the return value of build_quadratic_function, which is another function(lambda in this case)!
f(0) calls the lambda which is waiting
I'm trying to do the following: I want to write a function translate(f, c) that takes a given function f (say we know f is a function of a single variable x) and a constant c and returns a new function that computes f(x+c).
I know that in Python functions are first-class objects and that I can pass f as an argument, but I can't think of a way to do this without passing x too, which kind of defeats the purpose.
The trick is for translate to return a function instance.
def translate(f, c):
def func(x):
return f(x + c)
return func
Now the variable x is "free", and the names f and c are coming from an enclosing scope.
What about this?
def translate_func(f, c):
return lambda x: f(x + c)
To be used like, e.g.:
import math
g = translate_func(math.sin, 10)
print(g(1) == math.sin(10 + 1))
# True
EDIT
Note that this design pattern of a function taking a function as a parameter and returning another function is quite common in Python and goes by the name of "function decoration", with an associated convenience syntax. See PEP318 for more info on it.
def transalte(f, c):
def _inner(x):
return f(x+c)
return _inner
I would like to do something like the following:
def getFunction(params):
f= lambda x:
do stuff with params and x
return f
I get invalid syntax on this. What is the Pythonic/correct way to do it?
This way I can call f(x) without having to call f(x,params) which is a little more messy IMO.
A lambda expression is a very limited way of creating a function, you can't have multiple lines/expressions (per the tutorial, "They are syntactically restricted to a single expression"). However, you can nest standard function definitions:
def getFunction(params):
def to_return(x):
# do stuff with params and x
return to_return
Functions are first-class objects in Python, so once defined you can pass to_return around exactly as you can with a function created using lambda, and either way they get access to the "closure" variables (see e.g. Why aren't python nested functions called closures?).
It looks like what you're actually trying to do is partial function application, for which functools provides a solution. For example, if you have a function multiply():
def multiply(a, b):
return a * b
... then you can create a double() function1 with one of the arguments pre-filled like this:
from functools import partial
double = partial(multiply, 2)
... which works as expected:
>>> double(7)
14
1 Technically a partial object, not a function, but it behaves in the same way.
You can't have a multiline lambda expression in Python, but you can return a lambda or a full function:
def get_function1(x):
f = lambda y: x + y
return f
def get_function2(x):
def f(y):
return x + y
return f
I want to have some sort of reference to a function but I do not know if I need to use a def f(x) or a lambda of some kind.
For instance I'd like to print f(3) and have it output 9a, or is this not how python works?
Second question: Assuming I have a working function, how do I return the degree of it?
To create a function, you define it. Functions can do anything, but their primary use pattern is taking parameters and returning values. You have to decide how exactly it transforms parameters into the return value.
For instance, if you want f(x) to return a number, then a should also be a numeric variable defined globally or inside the function:
In [1]: def f(x):
...: a = 2.5
...: return a * x**2
...:
In [2]: f(3)
Out[2]: 22.5
Or maybe you want it to return a string like this:
In [3]: def f(x):
...: return str(x**2) + 'a'
...:
In [4]: f(3)
Out[4]: '9a'
You have to specify your needs if you need more help.
EDIT: As it turns out, you want to work with polynomials or algebraic functions as objects and do some algebraic stuff with them. Python will allow doing that, but not using standard data types. You can define a class for a polynomial and then define any methods or functions to get the highest power or anything else. But Polynomial is not a built-in data type. There may be some good libraries defining such classes, though.
Python (and most other computer languages) don't do algebra, which is what you'll need if you want symbolic output like this. But you could have a function f(a,x) which returns the result for particular (numerical) values of a:
def f(a, x):
return a*x*x
But if you want a program or language which actually does algebra for you, check out sympy or commercial programs like Mathematica.
If you are just working with polynomials, and you just need a data structure which deals well with them, check out numpy and its polynomial class.
I normally use lambda for short and simple functions:
f = lambda a, x: a * x**2
here a and x are parameters of my function. You need to enter a and x
f(2,4)
If you want a as a constant parameter eg. a=2:
f = lambda x: 2 * x**2
f(5)
if you have a list of input values of x, you can combine map with lambda.
it is straighforward and easily readable.
(*map(lambda x: 3 * x**2, [1,2,3,4]),)
or
list(map(lambda x: 3 * x**2, [1,2,3,4])
cheers!
def func():
print "F(x) = 2x + 3"
x = int(raw_input('Enter an integer value for x: '))
Fx = 2 * x + 3
return Fx
print func()
have fun :)
Cheese,
you can use the def function in Python to create a math function, you could type this:
def f(x):
return(2x + (3 + 3) * 11 + 88) # <- you could make your own function.
print(f(3))
Log:
220
Like THAT
or in this:
def f(a, x):
return((a + x) ** (a * x))
then...
print(f(1, 2))
Log...
6
I was wondering if it is possible in python to do the following:
def func1(a,b):
return func2(c,d)
What I mean is that suppose I do something with a,b which leads to some coefficients that can define a new function, I want to create this function if the operations with a,b is indeed possible and be able to access this outside of func1.
An example would be a simple fourier series, F(x), of a given function f:
def fourier_series(f,N):
...... math here......
return F(x)
What I mean by this is I want to creat and store this new function for later use, maybe I want to derivate it, or integrate or plot or whatever I want to do, I do not want to send the point(s) x for evaluation in fourier_series (or func1(..)), I simply say that fourier_series creates a new function that takes a variable x, this function can be called later outside like y = F(3)... if I made myself clear enough?
You should be able to do this by defining a new function inline:
def fourier_series(f, N):
def F(x):
...
return F
You are not limited to the arguments you pass in to fourier_series:
def f(a):
def F(b):
return b + 5
return F
>>> fun = f(10)
>>> fun(3)
8
You could use a lambda (although I like the other solutions a bit more, I think :) ):
>>> def func2(c, d):
... return c, d
...
>>> def func1(a, b):
... c = a + 1
... d = b + 2
... return lambda: func2(c,d)
...
>>> result = func1(1, 2)
>>> print result
<function <lambda> at 0x7f3b80a3d848>
>>> print result()
(2, 4)
>>>
While I cannot give you an answer specific to what you plan to do. (Looks like math out of my league.)
I can tell you that Python does support first-class functions.
Python may return functions from functions, store functions in collections such as lists and generally treat them as you would any variable.
Cool things such as defining functions in other functions and returning functions are all possible.
>>> def func():
... def func2(x,y):
... return x*y
... return func2
>>> x = func()
>>> x(1,2)
2
Functions can be assigned to variables and stored in lists, they can be used as arguments for other functions and are as flexible as any other object.
If you define a function inside your outer function, you can use the parameters passed to the outer function in the definition of the inner function and return that inner function as the result of the outer function.
def outer_function(*args, **kwargs):
def some_function_based_on_args_and_kwargs(new_func_param, new_func_other_param):
# do stuff here
pass
return some_function_based_on_args_and_kwargs
I think what you want to do is:
def fourier_series(f,N):
#...... math here......
def F(x):
#... more math here ...
import math #blahblah, pseudo code
return math.pi #whatever you want to return from F
if f+N == 2: #pseudo, replace with condition where f,N turn out to be useful
return F
else:
return None
Outside, you can call this like:
F = fourier_series(a,b)
if F:
ans = F(x)
else:
print 'Fourier is not possible :('
The important thing from Python's point of view are:
Yes, you can write a function inside a function
Yes, you can return a function from a function. Just make sure to return it using return F (which returns the function object) as compared to return F(x) which calls the function and returns the value
I was scraping through some documentation and found this.
This is a Snippet Like your code:
def constant(a,b):
def pair(f):
return f(a,b)
return pair
a = constant(1,2) #If You Print variable-> a then it will display "<function constant.
#<locals>.pair at 0x02EC94B0>"
pair(lambda a, b: a) #This will return variable a.
Now, constant() function takes in both a and b and return a function called "Anonymous Function" which itself takes in f, and calls f with a and b.
This is called "closures". Closures is basically an Instance of a Function.
You can define functions inside functions and return these (I think these are technically closures):
def make_f(a, b):
def x(a, b):
return a+b
return x(a, b)