Python function handle ala Matlab - python

In MATLAB it is possible to create function handles with something like
myfun=#(arglist)body
This way you can create functions on the go without having to create M-files.
Is there an equivalent way in Python to declare functions and variables in one line and to call them later?

Python's lambda functions are somewhat similar:
In [1]: fn = lambda x: x**2 + 3*x - 4
In [2]: fn(3)
Out[2]: 14
However, you can achieve similar effects by simply defining fn() as a function:
In [1]: def fn(x):
...: return x**2 + 3*x - 4
...:
In [2]: fn(4)
Out[2]: 24
"Normal" (as opposed to lambda) functions are more flexible in that they allow conditional statements, loops etc.
There's no requirement to place functions inside dedicated files or anything else of that nature.
Lastly, functions in Python are first-class objects. This means, among other things, that you can pass them as arguments into other functions. This applies to both types of functions shown above.

This is not quite the full answer. In matlab, one can make a file called funct.m:
function funct(a,b)
disp(a*b)
end
At the command line:
>> funct(2,3)
6
Then, one can create a function handle such as:
>> myfunct = #(b)funct(10,b))
Then one can do:
>> myfunct(3)
30
A full answer would tell how to do this in python.
Here is how to do it:
def funct(a,b):
print(a*b)
Then:
myfunct = lambda b: funct(10,b)
Finally:
>>> myfunct(3)
30

Turns out there is something that goes all the way back to 2.5 called function partials that are pretty much the exact analogy to function handles.
from functools import partial
def myfun(*args, first="first default", second="second default", third="third default"):
for arg in args:
print(arg)
print("first: " + str(first))
print("second: " + str(second))
print("third: " + str(third))
mypart = partial(myfun, 1, 2, 3, first="partial first")
mypart(4, 5, second="new second")
1
2
3
4
5
first: partial first
second: new second
third: third default

Related

Python specifying function as input [duplicate]

This question already has answers here:
how to define a function from a string using python
(4 answers)
Closed 4 years ago.
import math
def g(x):
return x**2+3
def Integrate(f, a , b, n):
h=(b-a)/n
result=0
for k in range(n):
x=k*h+h/2
result+=f(x)*h
return result
F=input("f:")
A=float(input("a:"))
B=float(input("b:"))
N=int(input("n:"))
print(Integrate(F, A, B, N))
Whenever i try to run this code, it reads F to be a string and gives an error when called in integrate(f, a, b, n). I found that there is no way in python to define F as a function, but calling a function in another function is definitely possible. Then how can i still pull this way of using an input to specify what function to use off?
error:
line 14, in Integrate
result+=f(x)*h
TypeError: 'str' object is not callable
You can input a function on the console by using a lambda (as a string), and use eval to convert the string to an actual function object. Your code would look like this:
F = eval(input("f:"))
On the console, if you want to integrate the function f(x) = 2 * x + 1, you'd input:
lambda x: 2 * x + 1
as a string. However, note that eval will execute (as Python code) whatever you input on the console, and this could be a security concern depending on how your program is used.
I don't know if you want to use function from math module, but if yes then you can obtain method from module by string like this:
function_to_call = getattr(math, f)
result += function_to_call(x) * h
When doing this you should surround with try except block to check if given function name exit in math module.

Postpone function execution syntactically

I've got a quite extensive simulation tool written in python, which requires the user to call functions to set up the environment in a strict order since np.ndarrays are at first created (and changed by appending etc.) and afterwards memory views to specific cells of these arrays are defined.
Currently each part of the environment requires around 4 different function calls to be set up, with easily >> 100 parts.
Thus I need to combine each part's function calls by syntactically (not based on timers) postponing the execution of some functions until all preceding functions have been executed, while still maintaining the strict order to be able to use memory views.
Futhermore all functions to be called by the user use PEP 3102 style keyword-only arguments to reduce the probability of input-errors and all are instance methods with self as the first parameter, with self containing the references to the arrays to construct the memory views to.
My current implementation is using lists to store the functions and the dict for each function's keyworded arguments. This is shown here, omitting the class and self parameters to make it short:
def fun1(*, x, y): # easy minimal example function 1
print(x * y)
def fun2(*, x, y, z): # easy minimal example function 2
print((x + y) / z)
fun_list = [] # list to store the functions and kwargs
fun_list.append([fun1, {'x': 3.4, 'y': 7.0}]) # add functions and kwargs
fun_list.append([fun2, {'x':1., 'y':12.8, 'z': np.pi}])
fun_list.append([fun2, {'x':0.3, 'y':2.4, 'z': 1.}])
for fun in fun_list:
fun[0](**fun[1])
What I'd like to implement is using a decorator to postpone the function execution by adding a generator, to be able to pass all arguments to the functions as they are called, but not execute them, as shown below:
def postpone(myfun): # define generator decorator
def inner_fun(*args, **kwargs):
yield myfun(*args, **kwargs)
return inner_fun
fun_list_dec = [] # list to store the decorated functions
fun_list_dec.append(postpone(fun1)(x=3.4, y=7.0)) # add decorated functions
fun_list_dec.append(postpone(fun2)(x=1., y=12.8, z=np.pi))
fun_list_dec.append(postpone(fun2)(x=0.3, y=2.4, z=1.))
for fun in fun_list_dec: # execute functions
next(fun)
Which is the best (most pythonic) method to do so? Are there any drawbacks?
And most important: Will my references to np.ndarrays passed to the functions within self still be a reference, so that the memory addresses of these arrays are still correct when executing the functions, if the memory addresses change in between saving the function calls to a list (or being decorated) and executing them?
Execution speed does not matter here.
Using a generators here doesn't make much sense. You are essentially simulating partial-application. Therefore, this seems like a use-case for functools.partial. Since you are sticking with key-word only arguments, this will work just fine:
In [1]: def fun1(*, x, y): # easy minimal example function 1
...: print(x * y)
...: def fun2(*, x, y, z): # easy minimal example function 2
...: print((x + y) / z)
...:
In [2]: from functools import partial
In [3]: fun_list = []
In [4]: fun_list.append(partial(fun1, x=3.4, y=7.0))
In [5]: fun_list.append(partial(fun2, x=1., y=12.8, z=3.14))
In [6]: fun_list.append(partial(fun2, x=0.3, y=2.4,z=1.))
In [7]: for f in fun_list:
...: f()
...:
23.8
4.3949044585987265
2.6999999999999997
You don't have to use functools.partial either, you can do your partial application "manually", just to demonstrate:
In [8]: fun_list.append(lambda:fun1(x=5.4, y=8.7))
In [9]: fun_list[-1]()
46.98
Since for commenting the code would be too complicated and it is based on juanpa.arrivillaga's answer, I'll add a full post with a short explanation what I mean by updating the reference to the arrays:
def fun1(*, x, y): # easy minimal example function 1
print(x * y)
arr = np.random.rand(5)
f1_lam = lambda:fun1(x=arr, y=5.)
f1_par = partial(fun1, x=arr, y=5.)
f1_lam() # Out[01]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
f1_par() # Out[02]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
# manipulate array so that the memory address changes and
# passing as reference is "complicated":
arr = np.append(arr, np.ones((2,1)))
f1_lam() # Out[03]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 5. 5.]
f1_par() # Out[02]: [0.55561103 0.9962626 3.60992174 2.55491852 3.9402079 ]
The behaviour of lambda is exactly what I was looking for in this question.
My examples with dict and decorators don't work, as well as functools.partial. Any idea why lambda is working? And just out of interest: Would there be any way to update the references to the arrays in the dict so that it would also work this way?

python, basic lambda function

I am a c++ guy, learning the lambda function in python and wanna know it inside out. did some seraches before posting here. anyway, this piece of code came up to me.
<1> i dont quite understand the purpose of lambda function here. r we trying to get a function template? If so, why dont we just set up 2 parameters in the function input?
<2> also, make_incrementor(42), at this moment is equivalent to return x+42, and x is the 0,1 in f(0) and f(1)?
<3> for f(0), does it not have the same effect as >>>f = make_incrementor(42)? for f(0), what are the values for x and n respectively?
any commments are welcome! thanks.
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
Yes, this is similar to a C++ int template. However, instead of at compile time (yes, Python (at least for CPython) is "compiled"), the function is created at run time. Why the lambda is used in this specific case is unclear, probably only for demonstration that functions can be returned from other functions rather than practical use. Sometimes, however, statements like this may be necessary if you need a function taking a specified number of arguments (e.g. for map, the function must take the same number of arguments as the number of iterables given to map) but the behaviour of the function should depend on other arguments.
make_incrementor returns a function that adds n (here, 42) to any x passed to that function. In your case the x values you tried are 0 and `1``
f = make_incrementor(42) sets f to a function that returns x + 42. f(0), however, returns 0 + 42, which is 42 - the returned types and values are both different, so the different expressions don't have the same effect.
The purpose is to show a toy lambda return. It lets you create a function with data baked in. I have used this less trivial example of a similar use.
def startsWithFunc(testString):
return lambda x: x.find(testString) == 0
Then when I am parsing, I create some functions:
startsDesctription = startsWithFunc("!Sample_description")
startMatrix = startsWithFunc("!series_matrix_table_begin")
Then in code I use:
while line:
#.... other stuff
if startsDesctription(line):
#do description work
if startMatrix(line):
#do matrix start work
#other stuff ... increment line ... etc
Still perhaps trival, but it shows creating general funcitons with data baked it.

How to use Overloading in Iron Python?

I wanted to use overloading in Iron Python but seems it's not working :
import sys
import clr
def af(a, b):
c = a+b
print c
return c
def af(j):
y = j*j
print y
return y
af(6,7)
af(5)
I get a error =\
Is there any way to use overloading ?
my purpose is to write a function : foo(doAction,numTimes)
when by default if I use foo(action): it will do it once,
or I'll write : foo(action,6)
thanks a lot!!!
IronPython might run on the CLR but that doesn't make it C#. In any kind of Python, you can only define a function once. Defining a function is really just assigning to a name, so in your code you assign a function to af, then assign another one to the same name, so the first one is simply discarded.
The way to do this in Python is via default arguments:
def aj(a, b=None):
if b is not None:
result = a + b
else:
result = a * a
print result
return result
For your actual use case of course you can define numtimes with a default of 1:
def foo(action, numtimes=1):
# whatever

what is the difference for python between lambda and regular function?

I'm curious about the difference between lambda function and a regular function (defined with def) - in the python level. (I know what is the difference for programmers and when to use each one.)
>>> def a():
return 1
>>> b = lambda: 1
>>> a
<function a at 0x0000000004036F98>
>>> b
<function <lambda> at 0x0000000004031588>
As we can see - python knows that b is a lambda function and a is a regular function. why is that? what is the difference between them to python?
They are the same type so they are treated the same way:
>>> type(a)
<type 'function'>
>>> type(b)
<type 'function'>
Python also knows that b was defined as a lambda function and it sets that as function name:
>>> a.func_name
'a'
>>> b.func_name
'<lambda>'
In other words, it influences the name that the function will get but as far as Python is concerned, both are functions which means they can be mostly used in the same way. See mgilson's comment below for an important difference between functions and lambda functions regarding pickling.
The only difference is that (a) the body of a lambda can consist of only a single expression, the result of which is returned from the function created and (b) a lambda expression is an expression which evaluates to a function object, while a def statement has no value, and creates a function object and binds it to a name.
In all other material respects they result in identical objects - the same scope and capture rules apply. (Immaterial differences are that lambda-created functions have a default func_name of "<lambda>". This may affect operation in esoteric cases - e.g. attempts to pickle functions.).
Both lambda and def create the same kind of function – they have the same kind of metadata and capabilities. Their technical difference is syntactical:
A lambda is an expression producing a function.
A def is a statement producing a function.
This is everything that dictates how they can be used. Other apparent differences simply come from the information lambda/def can capture.
>>> def def_func(): pass
>>> lambda_func = lambda: None
>>> type(def_func) == type(lambda_func)
True
Usage: Expression vs. Statement
A lambda is more flexible as expressions can be part of more language constructs.
# v--------------v arguments must be expressions
sort(values, key=lambda x: abs(x))
In contrast, a def is more powerful as it can consist of more language constructs.
def encode(num, base):
while num: # statements must be inside statements
num, bit = divmod(num, base)
yield bit
These differences derive directly from one being an expression and the other being a statement. Python has no special rules to decide where a lambda/def may be used.
Where the wild <lambda>s grow
The primary reason to assume lambda and def correspond to different kinds of function is metadata: lambda is often referred to as an "anonymous function" and miraculously it always produces a function <lambda>. Other quirks include "lambda functions can't be pickled", and recently typing also does "not work" for lambda.
That is because compared to def syntax, the lambda syntax has no way of specifying name, type annotations and similar. As such, Python simply fills in sane defaults for either: the name becomes <lambda> and annotations are left empty.
>>> identity = lambda a: a
>>> identity.__qualname__
'<lambda>'
>>> identity.__annotations__
{}
Since <lambda> is not a valid identifier, everything using this metadata to find the function – most prominently pickle – fails.
However, that does not make the function an "anonymous function" type. The metadata can be patched up to insert what def would provide:
>>> identity.__qualname__ = identity.__name__ = 'identity'
>>> identity
<function __main__.identity(a)>
Of course at that one point one can just use def…
First consider the diff b/w the two.
Lambda functions: are operator can have any number of arguments, but it can have only one expression. It cannot contain any statements and it returns a function object which can be assigned to any variable. They can be used in the block they were created.
def functions: Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organised and manageable. They can be called and used anywhere we want.
Here you can get more clear difference by following example.
Defining a function
def add(a,b):
return a+b
print(add(4,5))
Defining a lambda
add = lambda x, y : x + y
print(add(4,5))
Lambda is an inline function where we can do any functionality without a function name.
It is helpful when we use it as an argument to a higher-order function.
Eg: A function that takes in other functions as arguments.
Example of Function definition:
>>> def func(a, b):
return a * b
>>> func(2,3)
6
>>> type(func)
<class 'function'>
>>> func
<function func at 0x034B6E88>
Example of Lambda expression:
>>> multiply = lambda a, b: a * b
>>> multiply(2, 3)
6
>>> type(multiply)
<class 'function'>
>>> multiply
<function <lambda> at 0x034B6ED0>
Both returns same output value. Only object returned are different. "func" name for Function and for Lambda.
lambda creates an anonymous function. This idea has been taken from functional programming languages. In this way you can create and pass the function to other functions like map and filter. (look here)
You can pass normal functions to these functions too, but since mostly they are simple and they are not used anywhere else, it's inconvenient to go through the whole process of definfing a new function.
As an example take a look at this:
>>> a = [1, 2, 3, 4]
>>> print map( lambda x : x*2 + 1, a )
[3, 5, 7, 9, 11]

Categories

Resources