Your recursive function returns a string when the element is not in the (remaining) list:
if e in L:
# ...
return "{} is not in the list".format(e)
Because you are calling this function with a shorter and shorter list, that condition is always going to be true at some point.
You then try to concatenate that string to a list, in two places:
M = [L[1]] + removeAll(e, L[2:])
# ...
M = [L[0]] + removeAll(e, L[1:])
Don't return a string, return the list unmodified, so that it can be concatenated to that other element:
def removeAll(e, L):
if e in L:
if e == L[0]:
M = [L[1]] + removeAll(e, L[2:])
else:
M = [L[0]] + removeAll(e, L[1:])
return M
return L # no need to modify, the element is not present
You don't need to test if the element is elsewhere in the list. Only test the first element and not include it if it is a match. You'll also need to account for the possibility that L is empty:
def removeAll(e, L):
if not L:
return []
head = [] if L[0] == e else L[:1]
return head + removeAll(e, L[1:])
I used a slice again to create a list with one element.
If you must test if the element was not in the list, do so outside of the function:
original = [55, 77, 42, 11, 42, 88]
changed = removeAll(42, original)
if len(original) == len(changed):
return "42 is not in the list"
Of course, if recursion is not a course requirement for you, you'd be much better of using a list comprehension to filter the values:
def removeAll(e, L):
return [elem for elem in L if elem != e]
This returns a new list, with any elements equal to e filtered out.
If you are allowed to alter the list in-place, use list.remove() (and catch the ValueError:
def removeAll(e, L):
try:
L.remove(e)
except ValueError:
pass
return L
This does not create a copy; any other references to the original list will see the same change.
strwithlistwhich is what the error message is saying just because of the lastreturnwhich gives astr