Using simple Recursion to create a list - python

I want every element in l(which is a list) to be added to a.
When I run the function, it gives me '[]' every time. How can I fix this?
def sim(l):
a = []
if len(l)>0:
a = a.append(l.pop())
l.pop()
return sim(l)
return a

Several things are wrong:
You shouldn't use lowercase L for a variable name - it looks like one
At the top of the function you assign an empty list to a - ultimately sim will be called with an empty list, then a will be assigned an empty list, the conditional statement will fail and sim will return an empty list.
Inside the conditional statement you assign the return value of list.append() to a. The return value is None so whatever a was before, it gets wiped out.
Inside the conditional statement you pop() two items out of your control list
An empty list has a boolean value of false so there is no need to explicitly check its length,
def sim(el, a = None):
if el:
a.append(el.pop())
return sim(el, a)
return a
I was taught to write the base case of a recursive function as the first statement:
def sim(el, a = None):
if not el:
return a
a.append(el.pop())
return sim(el, a)

append() doesn't return anything but does update the existing list. In other words, by trying to assign the result of the append() method, you're setting a to nothing after you have already appended the item.

Your Code :def sim(l):
a = []
when you call Function recursively return sim(l) every time it is call sim(l) and a=[] is empty.
Try This :
def sim(l,a):
if len(l)>0:
a.append(l.pop())
print a
return sim(l,a)
return a

Is this a homework assignment where you're required to do it in a certain (overly complicated) way? Because if not, you can add one list to another in Python like so:
>>> l = [1, 2, 3]
>>> a = []
>>> a.extend(l)
>>> a
[1, 2, 3]

Related

How to return object when using `append` in Python

i have a function to append a list, something like this:
def append_func(element):
if xxxx:
new_list.append(element)
else:
[]
I have another function that uses append_func():
def second_func(item):
for i in item:
append_func(i)
if i run :
new_list = []
second _func(item)
new_list
This will return the list i want, but i can't do new_list = second _func(item) because in this case new_list will be a None.
I understand that append() will return a None type, but i'd like to return the appended list so I can use in other places result = second _func(xxx), what i have missed? Thanks.
According to the clarification you did in the comments you might want something like this. (I changed some of your placeholders so we have running code and a reproducible example)
The list is created by second_func so we get rid of the global list.
def append_func(data, element):
if 2 < element < 7:
data.append(element ** 2)
def second_func(items):
new_list = []
for i in items:
append_func(new_list, i)
return new_list
items = list(range(10))
result = second_func(items)
print(result)
The result is [9, 16, 25, 36].
simply tell python what to return:
def append_func(element):
if xxxx:
new_list.append(element)
else:
[]
return new_list # here, return whatever you want to return
if there is no "return" statement in the function, then the function returns None
The new_list you define before calling second_func is a global variable. Every time you call second_func() it will append the argument to the global variable. But the new_list is not restricted to the namespace of either function, so setting it as a return value doesn't make sense.

To return elements of a list from a function

I want to define a function that takes a list as its argument and then returns the elements in order.
For example:
def iterator(lis):
for e in range(len(lis)):
return lis[e]
l=input("Enter list elements:").split()
x=iterator(l)
print(x)
But this just returns the first value of the list as:
Enter list elements:12 23 34
12
How can I print all the values in successive lines?
You can use yield in order to build a generator, here's the official documentation about Generators
What is a generator in Python?
A Python generator is a function which returns a generator iterator
(just an object we can iterate over) by calling yield. yield may be
called with a value, in which case that value is treated as the
"generated" value.
I also want to share an example, be sure to read the comments:
def iterator(lis):
for e in range(len(lis)):
yield lis[e]
l=input("Enter list elements:").split()
# A generator returns an Iterable so you should
# loop to print
for number in iterator(l):
print(number)
# Or use list
result = list(iterator(l))
print(result)
Output
1
2
3
['1', '2', '3']
You probably want yield, as return causes the function call to end immediately. But yield just produces another iterator; you still need to iterate over the result to print them all, rather than simply printing the iterator itself.
def iterator(lis):
for e in range(len(lis)):
yield lis[e]
...
for element in x:
print(element)
Of course, you are pretty much just reimplementing the existing list iterator here; an equivalent definition would be
def iterator(lis):
yield from lis
What you might want instead is to do something like
x = '\n'.join(l)
print(x)
which creates a string by iterating over l and joining the elements using \n. The resulting multiline string can then be printed.
It will print only one element if you do return
def iterator(lis):
for e in range(len(lis)):
return lis[e]
l=input("Enter list elements:").split()
x=iterator(l)
for y in x: print(y)
Use:
def iterator(list):
for e in range(len(list)):
a= list[e]
print(a)
l=a,b,c=input().split()
a=iterator(l)
Use:
[print(i) for i in input("Enter list elements:").split(" ")]
return causes the function to stop after it hits the statement. So your for loop only ever runs once.
You could use yield as mentioned in the other answers, but I really don't think you need a function in this situation. Because the function is just going to return the list that it took as an argument. What you should do is something like this:
i = input("Enter list elements: ").split()
for x in i:
print(x)
It's that simple.
def iterator(lis):
for e in range(len(lis)):
print( lis[e])
l=input("Enter list elements:").split()
iterator(l)
if you want to do some operations for each item in the list, then you should accomodate those within the function.
Use of print instead of return will give you the expected output..try it once

appending LinkedLists items to list using Recursion

I have this:
def ppend(n):
lis = []
if n.rest == None:
pass
else:
lis.append(n.first)
ppend(n.rest)
return lis
n is a linked-list [1,2,3]
The output I am getting is :
[1]
But the output I am looking for is:
[1,2,3]
You are creating a new lis list on every recursion. (Incidentally, you might try to find more descriptive names.) Only the first list is returned, however, because you don't do anything with the other lists that result from recursion. Instead, you simply call the function, which simply creates a new list without doing anything with the value returned by the function. You can see this in the following line:
ppend(n.rest) # a new list is created but nothing is done with the result of the function
If you only plan to use the function once, you can simply move the lis assignment outside of the function:
lis = []
def ppend(n):
if n.rest is not None: # the first if statement appears unnecessary
lis.append(n.first)
ppend(n.rest)
return lis # or don't return it but simply refer to lis where you need to
The above approach, however, will not work as well if you plan to use the function multiple times and always need a new list. In the latter case, you might add a second function like this:
def make_ppend(n, lis): # add lis as a parameter to be explicit, but you could rely on scope instead of adding this extra parameter
if n.rest is not None:
lis.append(n.first)
make_ppend(n.rest, lis)
def ppend(n):
lis = [] # now in the local scope
make_ppend(n, lis)
return lis
I am guessing you are after something like the second solution.

recursive sorting in python

I am trying to run a sorting function recursively in python. I have an empty list that starts everything but everytime I try to print the list I get an empty list. here is my code. Any help would be greatly appreciated
def parse(list):
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list)
The value of newParse is not preserved between invocations of the function; you're setting it equal to [] (well, you're creating a new variable with the value []).
Since the only time you return is
newParse = []
if len(list) == 0:
return newParse`
you will always be returning [] because that is the value of newParse at that time.
Because you are doing this recursively, you are calling the function anew, without keeping the function's own state. Take a moment to consider the implications of this on your code.
Instead of initialising newParse = [], add an optional parameter newParse defaulting to a bogus value, and set newParse = [] if you receive that bogus value for newParse. Otherwise, you'll actually be getting the same list every time (i.e. the contents of the list object are being mutated). And newParse through in your tail call.
You also seem to have the problem that your definition and and the supposedly-recursive call refer to different functions.
def sort(list, newParse = None):
if newParse is None:
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list, newParse)
Here is what I think you are trying to do:
def recursive_sort(a_list):
def helper_function(list_to_be_sorted, list_already_sorted):
new = []
if len(list_to_be_sorted) == 0:
return list_already_sorted
else:
x = min(list_to_be_sorted)
list_to_be_sorted.remove(x)
new.append(x)
return helper_function(list_to_be_sorted, list_already_sorted + new)
return helper_function(a_list, [])
You shouldn't name variables list, as that is a builtin.
Also, if you are trying to implement a recursive sort function, you might want to look at quicksort, which is a very common (and fast) recursive sorting algorithm. What you have tried to implement is a recursive version of selection sort, which is much slower.
Also, if you actually need a sorting function, rather than just wanting to implement a recursive one, you should use the list method sort, or the function on an iterable sorted, both of which will be a lot faster than anything you could make in Python.

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