I have a list of variable names:
var_names = ['x','y']
and a function that takes vector input, e.g.
def f(vec):
return vec[0]+vec[1]
I want to build a function that creates a multi-input function that does the same thing as f, e.g.
def g(x,y):
return f([x,y])
Does anybody know how to create a function like g in an automated way? I tried this
def _create_multiInput_fcn(vector_fcn,var_list):
def g(*var_list):
out = vector_fcn(var_list)
return out
return g
g = _create_multiInput_fcn(f,var_list)
but that just gave me something with a signature like this:
<function __main__._create_multiInput_fcn.<locals>.f(*var_list)>
when I really want this:
<function __main__._create_multiInput_fcn.<locals>.f(x,y)>
I appreciate any help/advice that someone can give me. Thanks.
You can use the built-in function exec to define a function dynamically:
def _create_multiInput_fcn(vector_fcn,var_list):
exec('''
def g({0}):
return vector_fcn([{0}])
'''.format(','.join(var_list)), globals(), locals())
return g
g = _create_multiInput_fcn(f,var_list)
Related
The goal is to try and access any function's sub functions. I've looked around and I'm not too sure there is a way to do it. When I've tried using
functions = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isfunction)]
which returns the functions in some module (in the above __name__==__main__). When I have used that method, it doesn't return any sub functions. However I'd like to access sub functions that look something like
def f(x):
def y(x):
return x += 3
def z(x):
return x**2 - 1
x += y(x)
x += z(x)
return x
So it seems to me like there should be some way to access them with a magic method of f or some attribute of f. I have a hard time believing that those sub functions aren't stored as some attribute of f, but I have no idea.
In the end, what I need to do is to iterate through the sub functions of some function, so I thought the solution would look something like
for subfunc in f.__method_that_returns_subfuncs__():
if 'my_string' == subfunc.__name__:
out = subfunc(args)
I just need to be able to compare a string to a subfunction name then call that subfunction.
Thanks
There's no implicit list of functions to iterate over. You need to define it yourself. Simply functions can be assigned directly to a list by defining them with lambda expressions; more complex functions will need to be defined first, then added. Examples of each:
def f(x):
funcs = []
def y(x):
return x += 3
f.append(y)
f.append(lambda x: x**2 - 1)
for func in funcs:
x = func(x)
return x
If you care about the name, you can access it via the function object's __name__ attribute.
for func in funcs:
if func.__name__ == "some_func":
x = func(x)
I'm trying to implement a list of the same function called with different parameters, something like this:
def func1(num):
print("{}".format(num))
fl = [func1(1),func1(2),func1(3)]
for f in fl:
fl()
i got an error saying that 'list' object is not callable.
now, this works:
def func1():
print 1
def func2():
print 2
def func3():
print 3
fl = [func1,func2,func3]
for f in fl:
f()
what am i doing wrong?
From the code:
for f in f1:
f1()
Explanation:
As you defined f1 as of type list and you are using that variable as function call. But python expects the function name should be a string type. So got the error list() type is not callable
But when you changed code to :
for f in f1:
f()
here the f is of type string so python validated the type and so it didn't throw error
First, you're calling fl() which is trying to call the list as a function. that doesn't work.
In Python, putting () after a function evaluates the function and provides the return value. This means fl = [func1(1),func1(2),func1(3)] means "Create a list, and put the result of calling func1(1), func1(2), and func1(3)"
If you want to call the function later, then you can put the parameter into the list and walk through the list, or you can bind.
f = func1 # storing the function as a variable
fl = [1,2,3]
for v in fl:
f(v)
then you can do something like use lambda to bind:
f = func1 # storing the function as a variable
fl = [lambda :f(1), lambda :f(2), lambda :f(3)]
for v in fl:
v() # v is bound to the parameters, so you don't need to use a param
Use functools.partial:
from functools import partial
functions = [partial(func1, i) for i in range(1, 4)]
for fun in functions:
fun()
In your first example, I'm assuming that fl() is a typo, and you meant f() (because otherwise you'll be calling a list object, which isn't callable).
You know that func1(1) is calling the function and the result of this call is returned, so that in res = func1(1) the variable res will be the result of executing the function.. So, that list [func1(1), func1(2), ...] is a list of what this function returns. The function returns None, which isn't callable, that's why your code failed.
You want to call the function (not the result of calling the function!) with different arguments, and that's exactly what functools.partial is there for.
I'm newbie in Python, but the second time I encouter this problem.
Problem:
In some libraries there are functions with arguments. Sometimes there is argument as function, like this:
def somefun(fun):
x = [1,2,3]
z = fun(x)
return z
And I want to pass there some other function like this:
def func(x,y):
return x*y
which have more than one argument. I want to make one argument static, so somefun except func as argument.
Finally I want to make some kind of cycle where I can change static arg.
Something like this:
for i in xrange(1,9):
somefun(func(i,*))
Please do not offer me to change any functions. They are from library and it's not very comfortable to change them.
Thanks a lot!
You can use lambda statement:
somefun(lambda x: func(i, x))
It sure sounds like you are looking for functools.partial. From the docs:
functools.partial(func, *args, **keywords)
Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords.
In your example, you could pass partial(func, 10) as the argument to somefun. Or you could create the partial objects and use them in a loop:
for i in xrange(1,9):
somefun(partial(func, i))
My solution with decorator
from functools import wraps
import numpy as np
def p_decorate(f):
#wraps(f)
def wrapped(*args):
z = f(*args)
return z
return wrapped
#p_decorate
def myfunc(a,b):
"""My new function"""
z = np.dot(a,b)
return z
x = [1,2,3]
y = [4,2,0]
r = myfunc(x,y)
print (r)
print (myfunc.__name__)
print (myfunc.__doc__)
You can change myfunc as you wish.You can also insert more function layers.Without the use of this decorator factory,you would lose the name of myfunc and the docstring.
I'm trying to create function that get a number and return function. For example:
>>> const_function(2)(2)
2
>>> const_function(4)(2)
4
How can I return function as output? I've tried to write this:
def const_function(c):
def helper(x):
return c
return helper(x)
Why is this not working?
You're returning the result of calling the function. If you want to return the function itself, simply refer to it without calling it:
def const_function(c):
def helper(x):
return c
return helper # don't call it
Now you can use it with the desired results:
>>> const_function(2)
<function const_function.<locals>.helper at 0x0000000002B38D90>
>>> const_function(2)(2)
2
>>> const_function(4)(2)
4
Try:
return helper
When you do:
return helper(x)
it calculates the result of helper(x) and returns it. When you return helper it will return the function itself.
I should probably start by saying that I am relatively new to python, but I have coded in java and Matlab before.
In python, the code
def func(f):
return f
g = func(cos)
print(g(0))
gives the result
>1.0
as g now is defined as the cosine function.
I want to write a function that calculates the derivative of any provided function using a finite difference approach. The function is defined as
def derivator(f, h = 1e-8):
and would like to achieve the follwing:
g = derivator(cos)
print(g(0)) # should be about 0
print(g(pi/2)) # should be about -1
At the moment my derivator function looks like this
def derivator(f, h = 1e-8):
return (f(x+h/2)-f(x-h/2))/h
which definitely is wrong, but I am not sure how I should fix it. Any thoughts?
Your current derivator() function (which should probably be called differentiator()) uses an undefined variable x and would return a single value, if x were defined--the value of f'(x). You want to return a function that takes an x value. You can define an inner function and return it:
def fprime(x):
return (f(x+h/2)-f(x-h/2))/h
return fprime
Because you don't use that function anywhere else, though, you can use lambda instead, which is also shorter:
return lambda x: (f(x+h/2)-f(x-h/2))/h
The only thing PEP 8 says about lambdas is that you should not assign the result of the lambda to a variable, then return it:
fprime = lambda x: (f(x+h/2)-f(x-h/2))/h # Don't do this!
return fprime
Make an inner function inside your derivator function and return it:
from math import cos, pi
def derivator(f, h = 1e-8):
def g(x):
return (f(x+h/2)-f(x-h/2))/h
return g
g = derivator(cos)
print(g(0)) # 0.0
print(g(pi/2)) # -0.999999993923
f and h will be part of the closure of the returned function.
You can also return a lambda expression to make it one line:
return lambda x: (f(x+h/2)-f(x-h/2))/h