If an element e is in a list L, we are told to remove it and return the new list without the element.
With my current code, I get an error saying can only concatenate list (not "str") to list at the line M = [L[1]] + removeAll(e, L[2:]). Does anyone know how to fix this?
We are not allowed to use for or while statements. Thanks!
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 "{} is not in the list".format(e)
print (removeAll(42, [ 55, 77, 42, 11, 42, 88 ]))
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.
Your solution almost works. You need your simple case (e is not in L) to return the unmodified list. Don't return a string. You can optionally issue a print statement if the item is not found.
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
else:
#print "{} is not in the list".format(e) # optional
return L
This would be your code with the minimum amount of fixes to make it run properly.
The short, pythonic version that fits your requirements looks like this:
def removeAll(e, L):
return filter(lambda x: x!=e, L)
Alternatively, the equivalent code with a list comprehension:
def removeAll(e, L):
return [x for x in L if x!=e]
I don't know if this still fits your requirements because there's a for in there (while technically, a list comprehension is not a for loop).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With