Output of a function in Python - python

I have defined a function as below:
def Example(M):
......
.....
return A,B
M, A and B are matrices. The function returns A & B. At some point in my code i need only A. How to retrieve only A or B if required. I have tried Example(M).A but it throws error: Tuple object has no attribute A.

The function returns a tuple, which is just a sequence of values with no names.
To reference the n-th value (0-based) in a tuple x, use x[n]
X = Example(M)
A = X[0] # 1st value
However, if you have a function returning a sequence of values, you can use multiple assignment like this:
A, B = Example(M)

You should use A, B = Example(M).
You should also be careful about the indentation of your return statement. It should be indented once to the right.

Related

why python can't access global variable value with function parameter name change?

in these two pieces of code, why the second one gives error about local variable assignment? two codes are similar just function parameters is different, in the second one it's able to read the global variable why not in the first one what changes with parameter name change about symbol table?
first one:
def a(z):
z+=1
z=3
a(z)
second one:
def a(z):
b += 1
b = 5
a(b)
There aren't any global variables in use here.
In the first example, z is a parameter to the function, not a global. Note that when you increment z, it does not change in the calling scope, because the z inside the function is a copy of the z you passed in from outside the function.
In the second example, there is no b inside the function (the parameter is z), which is why you get an error inside the function when you try to modify it.
To do what you're trying to do, you should make the parameter a mutable object that contains the value you're trying to mutate; that way you can modify the value inside the function and the caller will have access to the new value. You could define a class for this purpose, or you could simply make it a single-element list:
def a(z):
z[0] += 1
b = [5]
a(b) # b == [6]
Or, if possible, a better approach IMO is not to depend on mutability, and to just return the new value, requiring the caller to explicitly re-assign it within its scope:
def a(z)
return z + 1
b = 5
b = a(b) # b == 6
You should concider def blocks as stand alone.
In the first snippet:
def a(z):
z+=1
What is z ? It's the first parameter of a
In the second snippet:
def a(z):
b += 1
What is b ? It is unknown. That's why this code fails.
You should also notice that in your first snippet, z inside the function is not the same than z=3:
>>> def a(z):
... z+=1
...
>>> z=3
>>> a(z)
>>>
>>> z
3
In the second code, the parameter is "z", and you tried to access that parameter with "b"
def a(z):
b += 1

Return specified output argument number from function

I have the following function:
def my_fun():
a = 1
b = 2
c = 3
return a,b,c
How do I now only get the second output argument from the function? I can for example do:
a,b,c = my_fun()
print(b)
But I don't want to specify a and c. Only b in this case. So I want to do something like:
print(my_fun([1])) # which should give me 2.
To get the second argument.
Just rearrange it slightly:
print(my_fun()[1])
Your function is returning a tuple, and you can subset tuples with integer indices like you would lists, because tuples are sequence types.
You'd index your return value
>>> my_fun()[1]
2
Otherwise as written my_fun([1]) looks like you are passing the list [1] as an argument to my_fun.
Note that as a convention _ is used to indicate a value that you do not care about, e.g.
_, b, _ = my_func()
If your function returns three values, you will always get three values. You can ignore them a few ways, though:
_, b, _ = my_fun()
b = my_fun()[1]

Python: anonymous variable for part of the return value of a function

Imagine I have a Python function foo that returns a tuple (a, b). I just want to use the second value returned, the b. Is there any syntax to tell python I don't want to use the first parameter? A sort of anonymous variable or something like (~, my_var) = foo() where the ~ would represent the syntax for the anonymous variable
Just unpack the tuple, use _ for non using variables:
_, bValue = foo()
Use the following syntax:
_, my_var = foo()
You could use the index and not store the first value at all:
def foo():
return (1,2)
b = foo()[1]
Output:
>>> b
2

How to pass tuple to a Matlab function from Python

I have a Matlab function that I'm calling from a python script:
import matlab.engine
eng = matlab.engine.start_matlab()
t = (1,2,3)
z = eng.tstFnc(t)
print z
The function tstFnc is as follows:
function [ z ] = tstFnc( a, b, c )
z = a + b + c
This does not work, however, as Matlab receives one input instead of three. Could this be made to work?
Note: this is a simplified case of what I want to do. In the actual problem I have a variable number of lists that I pass into a Matlab function, which is interpreted in the Matlab function using varargin.
As notes in the comments, the arguments need to be applied instead of passed as a tuple of length 1.
z = eng.tstFnc(*t)
This causes a call to tstFnc with len(t) arguments instead of a single tuple argument. Similarly you could just pass each argument individually.
z = eng.tstFnc(1, 2, 3)

How can I define functions in a for loop?

I'm trying to define a function of 3 unknown variables (k,m,c) but let's say I have to define it 100 times due to a different frequency f each time. Can I do this in a for loop in python and store all the functions in a list such that they are callable later?
This is what I have so far
index = -1
f_t = []
for f in inputs[:,0]:
index = index +1
def F_analytic(k, m, c):
F_t = k*m*c*f
return F_t
f_t.append([])
f_t[index].append(F_analytic)
but what I get in turn is a list of functions which are not callable:
Out[58]:
[[<function __main__.F_analytic>],
[<function __main__.F_analytic>],
[<function __main__.F_analytic>],
[<function __main__.F_analytic>],
[<function __main__.F_analytic>],
...
...
[<function __main__.F_analytic>],
[<function __main__.F_analytic>],
[<function __main__.F_analytic>]]
and the error is:
TypeError: 'list' object is not callable
Any help?
Thank you!
① You are nesting lists although you just want a flat list (of functions). See the answer of #BartoszKP on that.
② You want to create functions based on local variables. You can do this using lambdas, as #Harsh is proposing, or you can do it using defaulted variables:
def F_analytic(k, m, c, f=f): # notice the f=f here!
F_t = k*m*c*f
return F_t
③ You should consider whether having a list of functions really is what you want (as #Wooble already pointed out).
No, what you have is a list of lists of functions, with each inner list having 1 function.
Replace
f_t.append([])
f_t[index].append(F_analytic)
with
f_t.append(F_analytic)
(Although honestly, this whole approach seems rather suspicious; any reason you don't want one function with 4 parameters instead of 100 with 3?)
This is because you are creating a list of lists, you can call each function object like this:
f_t[0][0](1,2,3)
Alternatively, just create a list of functions:
f_t = []
for f in inputs[:,0]:
index = index +1
def F_analytic(k, m, c):
F_t = k*m*c*f
return F_t
f_t.append(F_analytic)
And as noted by other answers and comments, this all seems a rather strange approach. Do you really need to do this? :)
Sorry i dont think i answered the question properly, try this approach:
f_t = []
for f in input[:,0]:
f_t.append(lambda k, m, c: k*m*c*f)
You can call the functions easily by:
lets say you want to call the first one:
f_t[0](k,m,c)
Where k,m,c are your variables
Let's clean this code up:
#instead of an index counter, python provide `enumerate`
# so that you can have the counter as part of your loop
#index = -1
f_t = []
for index, f in enumerate(inputs[:,0]):
# index = index +1
def F_analytic(k, m, c):
#these two lines are redundant. You're just returning an expression
# so this whole function can be a lambda
F_t = k*m*c*f
return F_t
#why are you creating an inner list for each index position,
# and then appending the function to it?
#even if you wanted to have the inner list, you could do it in one step
f_t.append([])
f_t[index].append(F_analytic)
If we make the specified changes, we end up with:
f_t = [(lambda k, m, c: k*m*c*f) for f in inputs[:,0]]
Of course a much simpler approach would be simply to calculate the inputs to the product, including f, and multiply directly.

Categories

Resources