Generate variables for return - python

I have to return many variables from my function:
a = 5
b = 6
c = 8
d = 6
...
return a,b,c,d,e,f,g,h
Problem is that I would like to do it through array to save a code lines:
for (...):
ar[x] = ... # For x = a,b,c,d,e, ...
But I have to return variables in format 'return a,b,c,d,e' and I do not want to write it as:
return ar[a], ar[b], ar[c], ...
So can I use a generator for it and how? Somethig like:
return item for item in len(ar)

When you are "returning multiple variables", you are actually just returning a tuple. You can do this:
return tuple(ar)
or even
return ar
Assuming, of course, that your array contains everything you want to return in the correct order, and only that.
It would be nice to see more code, but it is likely that if you can fill that list using a loop, then it's semantically a single value (a homogenous collection) anyway.

You can do this:
def func(x):
# do something
lis = (#your values)
return lis
a,b,c,d,e = func(x)
This will return the values as a tuple, and unpacked at the other end

Use a generator expression and tuple:
return tuple(ar[x] for x in (a,b,c,d,e))
If indexes are continuous then you can use slicing:
return tuple(ar[2:8]) #If `ar` is a already a tuple then remove the tuple call
If you want to return the whole tuple/list itself then simply return it as is:
return ar #or return tuple(ar)
Note that returning a tuple is not compulsory, more discussion on it here: Python: Return tuple or list?

def values():
a = 3
b = 5
c = 9
d = 3
e = 5
return(a, b, c, d, e)
a1 = values()
print list(a1)
and you can edit the above function to return the tuple of variables
tuple(a,b,c,d,e)

Related

How to dynamically assign an unknown number of list elements?

I have this code which works but it's a big function block of IF..ELIF..ELSE. Is there a way to unpack or dynamically assign two lists. The thing is, sometimes mylist could have less elements than 4.
Input:
mylist=['1','2','3','4']
flag=['a','b','c','d']
Output:
A string object like 'a=1/b=2/c=3/d=4/' OR 'a=1/b=2/c=3/' if mylist only has 3 elements.
My current method is just like:
def myoutput(mylist, flag):
if flag=='3':
out = f'a={mylist[0]}/b={mylist[1]}/c={mylist[2]}/'
else:
out = f'a={mylist[0]}/b={mylist[1]}/c={mylist[2]}/d={mylist[3]}/'
return out
I tried to zip the two list, but I do not know the next steps and it doesn't really work:
tag_vars={}
for i in range((zip(mylist,flag))):
tag_vars[f"mylist{i}"] = flag[i]
print(tag_vars)
I would use zip for this task following way
mylist=['1','2','3','4']
flag=['a','b','c','d']
out = ''.join(f'{f}={m}/' for f,m in zip(flag,mylist))
print(out)
output
a=1/b=2/c=3/d=4/
Note that I used f,m with zip so f and m are corresponding elements from flag and mylist. Disclaimer: this solution assumes flag and mylist have always equal lengths.
You can use zip like this:
for a, b in zip(alist, blist): ...
I modified myoutput function to return your desired output
mylist=['1','2','3','4']
flag=['a','b','c','d']
def myoutput(mylist, flag):
result = []
for elem, f in zip(mylist, flag):
result.append(f"{f}={elem}")
return "/".join(result)
print(myoutput(mylist, flag)) # a=1/b=2/c=3/d=4
print(myoutput(mylist[:3], flag)) # a=1/b=2/c=3

Can we return one dataframe and one variable from a function in python? [duplicate]

I would like to return two values from a function in two separate variables.
For example:
def select_choice():
loop = 1
row = 0
while loop == 1:
print('''Choose from the following options?:
1. Row 1
2. Row 2
3. Row 3''')
row = int(input("Which row would you like to move the card from?: "))
if row == 1:
i = 2
card = list_a[-1]
elif row == 2:
i = 1
card = list_b[-1]
elif row == 3:
i = 0
card = list_c[-1]
return i
return card
And I want to be able to use these values separately. When I tried to use return i, card, it returns a tuple and this is not what I want.
You cannot return two values, but you can return a tuple or a list and unpack it after the call:
def select_choice():
...
return i, card # or [i, card]
my_i, my_card = select_choice()
On line return i, card i, card means creating a tuple. You can also use parenthesis like return (i, card), but tuples are created by comma, so parens are not mandatory. But you can use parens to make your code more readable or to split the tuple over multiple lines. The same applies to line my_i, my_card = select_choice().
If you want to return more than two values, consider using a named tuple. It will allow the caller of the function to access fields of the returned value by name, which is more readable. You can still access items of the tuple by index. For example in Schema.loads method Marshmallow framework returns a UnmarshalResult which is a namedtuple. So you can do:
data, errors = MySchema.loads(request.json())
if errors:
...
or
result = MySchema.loads(request.json())
if result.errors:
...
else:
# use `result.data`
In other cases you may return a dict from your function:
def select_choice():
...
return {'i': i, 'card': card, 'other_field': other_field, ...}
But you might want consider to return an instance of a utility class (or a Pydantic/dataclass model instance), which wraps your data:
class ChoiceData():
def __init__(self, i, card, other_field, ...):
# you can put here some validation logic
self.i = i
self.card = card
self.other_field = other_field
...
def select_choice():
...
return ChoiceData(i, card, other_field, ...)
choice_data = select_choice()
print(choice_data.i, choice_data.card)
I would like to return two values from a function in two separate variables.
What would you expect it to look like on the calling end? You can't write a = select_choice(); b = select_choice() because that would call the function twice.
Values aren't returned "in variables"; that's not how Python works. A function returns values (objects). A variable is just a name for a value in a given context. When you call a function and assign the return value somewhere, what you're doing is giving the received value a name in the calling context. The function doesn't put the value "into a variable" for you, the assignment does (never mind that the variable isn't "storage" for the value, but again, just a name).
When i tried to to use return i, card, it returns a tuple and this is not what i want.
Actually, it's exactly what you want. All you have to do is take the tuple apart again.
And i want to be able to use these values separately.
So just grab the values out of the tuple.
The easiest way to do this is by unpacking:
a, b = select_choice()
I think you what you want is a tuple. If you use return (i, card), you can get these two results by:
i, card = select_choice()
def test():
....
return r1, r2, r3, ....
>> ret_val = test()
>> print ret_val
(r1, r2, r3, ....)
now you can do everything you like with your tuple.
def test():
r1 = 1
r2 = 2
r3 = 3
return r1, r2, r3
x,y,z = test()
print x
print y
print z
> test.py
1
2
3
And this is an alternative.If you are returning as list then it is simple to get the values.
def select_choice():
...
return [i, card]
values = select_choice()
print values[0]
print values[1]
you can try this
class select_choice():
return x, y
a, b = test()
You can return more than one value using list also. Check the code below
def newFn(): #your function
result = [] #defining blank list which is to be return
r1 = 'return1' #first value
r2 = 'return2' #second value
result.append(r1) #adding first value in list
result.append(r2) #adding second value in list
return result #returning your list
ret_val1 = newFn()[1] #you can get any desired result from it
print ret_val1 #print/manipulate your your result

Apply map on *args in Python where *args are lists

I want to get a list of lists consisting of only 0 and 1 and map the first element of the first list with the first element of the second list and so on.
My mapping function is this:
def intersect(*values):
result = values[0]
for idx in range(1, len(values)):
result = result << 1
result = result | values[idx]
return result
I'm trying to do this but it does not work:
def intersect_vectors(*vectors):
return list(map(intersect, zip(vectors)))
It would work if I would knew the number of vectors and would have a function like this:
def intersect_vectors(v1, v2, v3):
return list(map(intersect, v1,v2,v3))
Example:
intersect_vectors([1,1],[1,0],[0,1]) would return [6,5] which is [b110, b101]
You can explode your vectors with * and it will work the same:
def intersect_vectors(*vectors):
return list(map(intersect, *vectors))
The simplest solution is probably to delegate the functionality of transforming between a list and 'arguments' to a lambda:
return [list(map((lambda v: intersect(*v)), zip(vectors)))]

Python: can a function return a string?

I am making a recursive function that slices string until it is empty. When it is empty it alternatively selects the characters and is supposed to print or return the value. In this case I am expecting my function to return two words 'Hello' and 'World'. Maybe I have got it all wrong but what I don't understand is that my function doesn't let me print or return string. I am not asking for help but I'd like some explanation :) thanks
def lsubstr(x):
a= ''
b= ''
if x == '':
return ''
else:
a = a + x[0:]
b = b + x[1:]
lsubstr(x[2:])
#print (a,b)
return a and b
lsubstr('hweolrllod')
so I changed my code to this:
def lsubstr(x):
if len(x) <1:
return x
else:
return (lsubstr(x[2:])+str(x[0]),lsubstr(x[2:])+str(x[1]))
lsubstr('hweolrllod')
and what I am trying to make is a tuple which will store 2 pairs of characters and concatenate the next ones,
the error I get is
TypeError: Can't convert 'tuple' object to str implicitly
what exactly is going wrong, I have checked in visualization, it has trouble in concatenating.
The and keyword is a boolean operator, which means it compares two values, and returns one of the values. I think you want to return a tuple instead, like this:
...
return (a, b)
And then you can access the values using the indexing operator like this:
a = lsubstr( ... )
a[0]
a[1]
Or:
word1, word2 = lsubstr( ... )

Why does list.append() return None? [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 2 years ago.
I am trying to calculate a postfix expression using Python, but it did not work. I think this is maybe a Python-related problem.
Any suggestions?
expression = [12, 23, 3, '*', '+', 4, '-', 86, 2, '/', '+']
def add(a,b):
return a + b
def multi(a,b):
return a* b
def sub(a,b):
return a - b
def div(a,b):
return a/ b
def calc(opt,x,y):
calculation = {'+':lambda:add(x,y),
'*':lambda:multi(x,y),
'-':lambda:sub(x,y),
'/':lambda:div(x,y)}
return calculation[opt]()
def eval_postfix(expression):
a_list = []
for one in expression:
if type(one)==int:
a_list.append(one)
else:
y=a_list.pop()
x= a_list.pop()
r = calc(one,x,y)
a_list = a_list.append(r)
return content
print eval_postfix(expression)
Just replace a_list = a_list.append(r) with a_list.append(r).
Most functions, methods that change the items of sequence/mapping does return None: list.sort, list.append, dict.clear ...
Not directly related, but see Why doesn’t list.sort() return the sorted list?.
The method append does not return anything:
>>> l=[]
>>> print l.append(2)
None
You must not write:
l = l.append(2)
But simply:
l.append(2)
In your example, replace:
a_list = a_list.append(r)
to
a_list.append(r)
For return data on append use:
b = []
a = b.__add__(['your_data_here'])
append function mutates the list and it returns None. This is the piece of code which does that http://hg.python.org/cpython/file/aa3a7d5e0478/Objects/listobject.c#l791
listappend(PyListObject *self, PyObject *v)
{
if (app1(self, v) == 0)
Py_RETURN_NONE;
return NULL;
}
So, when you say
a_list = a_list.append(r)
you are actually assigning a_list with None. So, the next time when you refer to a_list, it is not pointing to the list but the None. So, as others have suggested, change
a_list = a_list.append(r)
to
a_list.append(r)
Functions like list.append(),list.sort() don't return anything.
e.g
def list_append(p):
p+=[4]
function list_append doesn't have an return statement.so when you run following statements:
a=[1,2,3]
a=list_append(a)
print a
>>>None
but when you run following statements:
a=[1,2,3]
list_append(a)
print a
>>>[1,2,3,4]
That's it.so,hoping it can help you.
List methods can be divided in two types those who mutate the lists in place and return None (literally) and those who leave lists intact and return some value related to the list.
First category:
append
extend
insert
remove
sort
reverse
Second category:
count
index
The following example explains the differences.
lstb=list('Albert')
lstc=list('Einstein')
lstd=lstb+lstc
lstb.extend(lstc)
# Now lstd and lstb are same
print(lstd)
print(lstb)
lstd.insert(6,'|')
# These list-methods modify the lists in place. But the returned
# value is None if successful except for methods like count, pop.
print(lstd)
lstd.remove('|')
print(lstd)
# The following return the None value
lstf=lstd.insert(6,'|')
# Here lstf is not a list.
# Such assignment is incorrect in practice.
# Instead use lstd itself which is what you want.
print(lstf)
lstb.reverse()
print(lstb)
lstb.sort()
print(lstb)
c=lstb.count('n')
print(c)
i=lstb.index('r')
print(i)
pop method does both. It mutates the list as well as return a value.
popped_up=lstc.pop()
print(popped_up)
print(lstc)
just a thought, instead of those functions (which manipulates the actual data) returning None, they should have returned nothing.
Then atleast the user would have caught the issue as it would have throwed an error stating some assignment error!!
Comment your thoughts!!
Just in case somebody ends here, I encountered this behavior while trying to append on a return call
This works as expected
def fun():
li = list(np.random.randint(0,101,4))
li.append("string")
return li
This returns None
def fun():
li = list(np.random.randint(0,101,4))
return li.append("string")

Categories