This question already has answers here:
Python list comprehension: test function return
(2 answers)
Closed 6 years ago.
I have a function which has a for loop like this
def my_func():
order = [1,2,3,4,5,6,7]
my_list = []
for o in order:
tmp = is_odd(o)
if tmp:
my_list.append(tmp)
return my_list
def is_odd(n):
if n%2 != 0:
return n
else:
return False
I want to convert it into one line python for loop. I did it like this
def my_func():
order = [1,2,3,4,5,6,7]
my_list = [is_odd(o) for o in order if is_odd(o)]
return my_list
def is_odd(n):
if n%2 != 0:
return n
else:
return False
The problem with this code is that it call is_odd function twice in each loop iteration. Is there any other way to convert loop into one line loop and calling is_odd function only once?
(This is not original code. Just an example)
As described in the question's answers that I've linked as duplicate to your question:
Python list comprehension: test function return
You'd create a generator (or a list) that produces the (intermediate) results of your function's calls and produce the filtered output based on that:
Example:
def my_func():
order = [1,2,3,4,5,6,7]
intermediate_results = (is_odd(o) for o in order)
# alternatively filter using `filter(None, intermediate_results)`
return [i for i in intermediate_results if i]
In this case, you can use the filter function. E.g. my_list = filter(is_odd, order).
If you have similar needs, look at the itertools module.
Hi – it looks like you return the function is_odd(o) (thus run it again) for the instances of o where the function is_odd(o) returns true. Following should only run once:
def my_func():
order = [1,2,3,4,5,6,7]
my_list = [o for o in order if is_odd(o)]
return my_list
Related
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 1 year ago.
I have been studying coding on my own and some how I have been stuck, not being able to compile the same solution:
my code:
def append_size(lst):
num = len(lst)
lst = lst.append(num)
return lst
print(append_size([23, 42, 108]))
solution:
def append_size(lst):
lst.append(len(lst))
return lst
print(append_size([23, 42, 108]))
first one gives out "None" and second one gives out the list.
tell me why.
Thank you🤘
Its because in the first one, you assign lst the result of the call lst.append()
The .append() method returns None so assigning it to a variable and returning it... Would return None
While in the second case. No such assignment takes place
# first code
lst = lst.append(x) # end up assigning None to lst
#second code
lst.append(x) # no unwanted assignments
.append() wont return anything (just None), it just modifies a list. So when you do lst = lst.append(list) you are basically assigning None to lst.
Try this instead
def append_size(lst):
num = len(lst)
lst.append(num)
return lst
print(append_size([23, 42, 108]))
This question already has answers here:
Alternatives for returning multiple values from a Python function [closed]
(14 answers)
Closed 2 years ago.
I am learning programming by myself. In my code, I am practicing nested looping, and I am doing an exercise to see if I can find all matching numbers from a list. However it is returning only the first number, and it is not going through the whole list, Can someone please help? Thanks in advance
mylist = []
def intersection(lst1, lst2):
for n in lst1:
for o in lst2:
if n == o:
mylist.append(n)
return mylist
The return statement needs to be unindented such that it is placed at the end of the function and not inside the loop:
def intersection(lst1, lst2):
mylist = []
for n in lst1:
for o in lst2:
if n == o:
mylist.append(n)
return mylist
Before, when it was immediately after mylist.append(n), the function returns the result immediately after that line of code, which is triggered once the first overlapping element is found (ie our answer will only have one element). If we put it at the end of the function instead, it will only return once the algorithm is complete.
I also moved the definition of mylist inside the function, otherwise you'd be overwriting your results if you call the function multiple times.
Also, since you're learning python, I also might look into list comprehensions, which are considered more "pythonic", are more concise, and in many cases execute faster:
def intersection(lst1, lst2):
return [n for n in lst1 for o in lst2 if n == o]
However, both of the above implementations will have duplicates in the result of an overlapping element appears more than once in either list. For example:
intersection([1,1,2,3], [1,1,2,4])
>>> [1,1,1,1,2]
A better implementation would use python sets and the built in set intersection operator:
def intersection(lst1, lst2):
return list(set(lst1) & set(lst2))
intersection([1,1,2,3], [1,1,2,4])
>>> [1,2]
Once you return something in a function, there's no going back to the previous call to retrieve more values. Unindent the return statement:
mylist = []
def intersection(lst1, lst2):
for n in lst1:
for o in lst2:
if n == o:
mylist.append(n)
return mylist
You can also use the yield statement:
def intersection(lst1, lst2):
for n in lst1:
for o in lst2:
if n == o:
yield n
print(list(intersection([1, 2, 3], [2, 3, 4])))
Output:
[2, 3]
Look at the return statement, the last line of your code. You are returning from the inner 'for' loop as soon as you find a match; so your code will return and never come back to the 'def intersection(lst1, lst2)' function. Try to work on the issue and see if you can find the mistake.
You simply need to unindent the return statement so both loops can finish before it returns.
def intersection(lst1, lst2):
my_list = []
for n in lst1:
for o in lst2:
if n == o:
my_list.append(n)
return my_list
It's because of your return !
def intersection():
lst1=["1","7","5"]
lst2 = ["8","7"]
mylist=[]
for n in lst1:
for o in lst2:
if n == o:
mylist.append(n)
print(mylist)
intersection()
Here, the return will be executed directly the first time the code enters the if statement.
1- Just unindent your return myList so that it executes after your loops, not during.
2 - Also, it's a bit strange that you have a global variable that you return in the function. I'd suggest keeping things tidy, and return a fresh new list, that will prevent some potential bugs.
def intersection(lst1, lst2):
mylist = []
for n in lst1:
for o in lst2:
if n == o:
mylist.append(n)
return mylist
This question already has answers here:
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed last month.
I was trying to use *args with a for loop in python, however I don't see how to return all the values passed to the function, which should return all the even numbers
def f_even(*args):
for item in args:
if item%2 == 0:
return item
The above code returns only the first value, as I guess after the return it goes out of the function. Indeed, if I use print instead, it works
I'm trying to find a way to return a tuple with all the even numbers when I pass let's say (1,2,3,4,5) to the function
Thank you!
In python you can use list comprehension to do this. will make you code more readable and will shrink it too.
def f_even(*args):
return [elem for elem in args if elem % 2 == 0]
You could slightly modify you function and make it a generator by using yield. This way your function wont end after returning first even number but will keep yielding them one by one.
def f_even(*args):
for item in args:
if item%2 == 0:
yield item
for i in f_even(1,2,3,4,5):
print(i)
Output:
2
4
Or if you want to store all yielded values:
even_numbers = list(f_even(1,2,3,4,5))
print(even_numbers) # -> [2, 4]
Done, thank you all!!
def f_even(*args):
mylist = []
for item in args:
if item%2 == 0:
mylist.append(item)
return mylist
Hello so I was wondering how can I 'print' the list of numbers generated by these functions that take the values from the list and squares them. Thanks!!!
def square(list):
return [i ** 2 for i in list]
def square(list):
return map(lambda x: x ** 2, list)
def square(list):
for i in list:
yield i ** 2
def square(list):
ret = []
for i in list:
ret.append(i ** 2)
return ret
Printing a list by using print, for example:
print(', '.join(map(str, square([5,3,2]))
First off, you need different function names, or else when you call it, python will only take the last one.
To answer your question, it is as easy as using a print statement. Simply print the return of the function while using a list as the argument.
square_list = [1,2,3]
print square(square_list)
If you wanted to try a different way, putting the print statement in the function also works.
For example:
def square(list):
print [i ** 2 for i in list] # Instead of return
The downside of this is you cannot store it as a variable or append it to a list later on.
Happy coding!
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")