Return specified output argument number from function - python

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]

Related

Output of a function in 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.

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

What is the best way to return items in Python that meet a specific condition

The code I'm currently using is:
def f(*args):
lst=[str(i) for i in args]
if len(lst)==1:lst = lst[0]
return lst
What I would like is:
a=f(1) #'1', not [1]
a,b = f(1,2) #'1', '2'
Only one argument would be a list, which would be represented by a.
What alternative exists aside from using an if statement?
Yes:
return lst[0] if len(lst) == 1 else lst
Returning different types like that can be confusing. I'd recommend using
a = f(1)[0]
or
[a] = f(1)
or
a, = f(1)
If I understand you correctly, no. If you accept variable arguments with *args, then you get a list, even if there is only one argument.
You could of course separate the first argument with def f(first, *rest), but then you have to do special-casing to combine the elements when you do want a list.
I suggest to use yield:
def f(*args):
for i in args:
yield str(i)
a, = f(1)
print a
a, b = f(1, 2)
print a, b
which returns:
1
1 2
is it what you want?

How can a function return a dynamic value that depends on the number of receivers in Python?

I was trying to do a "strange" (but useful in my case) function that can return a dynamic list whose len depends on the amount of receiver.
For example:
f() returns a dynamic list of None, so I can do the following:
a = f() => a = None
a, b = f() => a=b= None
(a, b) = f() => a=b= None
(a, b, c, d, e, f) = f() => a=b=c=d=e=f= None
I think this might be done via generator comprehension or iterator, but I was blocked on how to get the amount of recevier. Maybe I was in the wrong direction. Would you advise me some tips?
Any helps will be appreciated.
Many Thank,
Tiezhen
This is not possible in Python. The function on the right hand site has no knowledge of the context it was called in. The right hand site is evaluated before any of the name bindings take place.
Unfortunately, Python unpacks returned tuples using the Pythonic "it's easier to ask forgiveness than permission" approach. That is, if you have a statement:
a,b,c = f()
Behind the scenes, it's doing something along the lines of:
try:
a = returned[0]
b = returned[1]
c = returned[2]
except IndexError:
raise ValueError('need more than k values to unpack')
try:
_ = returned[4]
except IndexError:
pass
else:
raise ValueError('too many values to unpack')
So it's discovering dynamically the number of values returned. Unfortunately, that precludes us from being clever and creating a new type for handling variable returns:
class VariableReturn(object):
def __getitem__(self, index):
return ...
In Python 3, you can sort of do what you're asking, but the burden is on the caller, not the function being called. The function should always return the same number of results, but we'll trap the remaining results using extended tuple unpacking, as shown in this StackOverflow question.
Using this approach, you can return as many results as you'd like, but you need to always return at least as many as you need in the maximal case. The rest get packed into a trailing tuple.
a,*others = f()
a,b,*others = f()
a,b,c,*others = f()
If you don't mind using Python 3, you can ignore what you don't need, for example:
a, b, c, d, *_ = (x for x in range(100))
Try this:
def f(n):
return (None, ) * n
For example:
a, b, c = f(3)
... That's about as far as you can get, since in Python there's no way to know how many variables are in the left-hand side of an assignment.
Can't be done.
Functions in Python return one value, only. While it may sometimes look like more, it's still just one value: a tuple. Multiple assignment is then a process of tuple unpacking.
Your question then can be restated: can we create an object that acts like a tuple of varying length, depending on how many values need to be unpacked? And that's simply not made available as an option.
Probably the closest I can think of is to use a generator and get the desired number of items with itertools.islice:
a = itertools.count()
x, y, z = itertools.islice(a, 3) # 0, 1, 2
u, v = itertools.islice(a, 2) # 3, 4
But that's pretty far from what was hoped for.
pretty not nice but perhaps this helps you:
def f(x):
for i in x:
globals()[i] = None
f(['a','b','c'])

Ignore python multiple return value

Say I have a Python function that returns multiple values in a tuple:
def func():
return 1, 2
Is there a nice way to ignore one of the results rather than just assigning to a temporary variable? Say if I was only interested in the first value, is there a better way than this:
x, temp = func()
You can use x = func()[0] to return the first value, x = func()[1] to return the second, and so on.
If you want to get multiple values at a time, use something like x, y = func()[2:4].
One common convention is to use a "_" as a variable name for the elements of the tuple you wish to ignore. For instance:
def f():
return 1, 2, 3
_, _, x = f()
If you're using Python 3, you can you use the star before a variable (on the left side of an assignment) to have it be a list in unpacking.
# Example 1: a is 1 and b is [2, 3]
a, *b = [1, 2, 3]
# Example 2: a is 1, b is [2, 3], and c is 4
a, *b, c = [1, 2, 3, 4]
# Example 3: b is [1, 2] and c is 3
*b, c = [1, 2, 3]
# Example 4: a is 1 and b is []
a, *b = [1]
The common practice is to use the dummy variable _ (single underscore), as many have indicated here before.
However, to avoid collisions with other uses of that variable name (see this response) it might be a better practice to use __ (double underscore) instead as a throwaway variable, as pointed by ncoghlan. E.g.:
x, __ = func()
Remember, when you return more than one item, you're really returning a tuple. So you can do things like this:
def func():
return 1, 2
print func()[0] # prints 1
print func()[1] # prints 2
The best solution probably is to name things instead of returning meaningless tuples (unless there is some logic behind the order of the returned items). You can for example use a dictionary:
def func():
return {'lat': 1, 'lng': 2}
latitude = func()['lat']
You could even use namedtuple if you want to add extra information about what you are returning (it's not just a dictionary, it's a pair of coordinates):
from collections import namedtuple
Coordinates = namedtuple('Coordinates', ['lat', 'lng'])
def func():
return Coordinates(lat=1, lng=2)
latitude = func().lat
If the objects within your dictionary/tuple are strongly tied together then it may be a good idea to even define a class for it. That way you'll also be able to define more complex operations. A natural question that follows is: When should I be using classes in Python?
Most recent versions of python (≥ 3.7) have dataclasses which you can use to define classes with very few lines of code:
from dataclasses import dataclass
#dataclass
class Coordinates:
lat: float = 0
lng: float = 0
def func():
return Coordinates(lat=1, lng=2)
latitude = func().lat
The primary advantage of dataclasses over namedtuple is that its easier to extend, but there are other differences. Note that by default, dataclasses are mutable, but you can use #dataclass(frozen=True) instead of #dataclass to force them being immutable.
Here is a video that might help you pick the right data class for your use case.
Three simple choices.
Obvious
x, _ = func()
x, junk = func()
Hideous
x = func()[0]
And there are ways to do this with a decorator.
def val0( aFunc ):
def pick0( *args, **kw ):
return aFunc(*args,**kw)[0]
return pick0
func0= val0(func)
This seems like the best choice to me:
val1, val2, ignored1, ignored2 = some_function()
It's not cryptic or ugly (like the func()[index] method), and clearly states your purpose.
If this is a function that you use all the time but always discard the second argument, I would argue that it is less messy to create an alias for the function without the second return value using lambda.
def func():
return 1, 2
func_ = lambda: func()[0]
func_() # Prints 1
This is not a direct answer to the question. Rather it answers this question: "How do I choose a specific function output from many possible options?".
If you are able to write the function (ie, it is not in a library you cannot modify), then add an input argument that indicates what you want out of the function. Make it a named argument with a default value so in the "common case" you don't even have to specify it.
def fancy_function( arg1, arg2, return_type=1 ):
ret_val = None
if( 1 == return_type ):
ret_val = arg1 + arg2
elif( 2 == return_type ):
ret_val = [ arg1, arg2, arg1 * arg2 ]
else:
ret_val = ( arg1, arg2, arg1 + arg2, arg1 * arg2 )
return( ret_val )
This method gives the function "advanced warning" regarding the desired output. Consequently it can skip unneeded processing and only do the work necessary to get your desired output. Also because Python does dynamic typing, the return type can change. Notice how the example returns a scalar, a list or a tuple... whatever you like!
When you have many output from a function and you don't want to call it multiple times, I think the clearest way for selecting the results would be :
results = fct()
a,b = [results[i] for i in list_of_index]
As a minimum working example, also demonstrating that the function is called only once :
def fct(a):
b=a*2
c=a+2
d=a+b
e=b*2
f=a*a
print("fct called")
return[a,b,c,d,e,f]
results=fct(3)
> fct called
x,y = [results[i] for i in [1,4]]
And the values are as expected :
results
> [3,6,5,9,12,9]
x
> 6
y
> 12
For convenience, Python list indexes can also be used :
x,y = [results[i] for i in [0,-2]]
Returns : a = 3 and b = 12
It is possible to ignore every variable except the first with less syntax if you like. If we take your example,
# The function you are calling.
def func():
return 1, 2
# You seem to only be interested in the first output.
x, temp = func()
I have found the following to works,
x, *_ = func()
This approach "unpacks" with * all other variables into a "throwaway" variable _. This has the benefit of assigning the one variable you want and ignoring all variables behind it.
However, in many cases you may want an output that is not the first output of the function. In these cases, it is probably best to indicate this by using the func()[i] where i is the index location of the output you desire. In your case,
# i == 0 because of zero-index.
x = func()[0]
As a side note, if you want to get fancy in Python 3, you could do something like this,
# This works the other way around.
*_, y = func()
Your function only outputs two potential variables, so this does not look too powerful until you have a case like this,
def func():
return 1, 2, 3, 4
# I only want the first and last.
x, *_, d = func()

Categories

Resources