I'm doing some recursion exercises on lists in python3 and was running into a problem where I would have my returned list filled with some unwwanted None-types.
This particular exercise is for creating a function that removes all vowel strings from a list. All the elements in the input list are strings of length one, but the list can contain more lists as well.
def without_vowels(arg):
vowels = "aeiuoåäöAEIUOÅÄÖ"
if not arg:
return arg
elif isinstance(arg, str):
if not arg in vowels:
return arg
else:
return ""
elif isinstance(arg, list):
if without_vowels(arg[0]) == "":
return without_vowels(arg[1:])
else:
return [without_vowels(arg[0])] + without_vowels(arg[1:])
Expected output:
>>> test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
>>> without_vowels(test)
>>> [['h', 'j'], ['t', 's', 'c']]
Initially, to "remove" the vowels upon detection I would simply not return anything. This resulted in None-types being added to the list.
Output without work-around (lines 10,11, 14-16 removed) :
>>> without_vowels(test)
>>> [None, ['h', None, 'j'], ['t', None, 's', 'c', None]]
To work around this problem I changed the code to return an empty string when vowels where found, and added a "pre-check" before calling on the function again to continue, basically just checking if the function call would find a vowel (and return "") and in that case skip ahead to the next part of the list argument.
I feel like I'm missing something obvious and there should be a better solution without using a work-around like this.
Thanks
Edit: This particular exercise is meant to be solved with double recursion, not with a combination of iteration and single recursion
This particular exercise is meant to be solved with double recursion, not with a combination of iteration and single recursion
My approach to recursion is to keep it simple and let the recursion do the work for you:
VOWELS = set("aeiuoåäöAEIUOÅÄÖ")
def without_vowels(argument):
if not argument:
return argument
head, *tail = argument
if isinstance(head, list):
head = without_vowels(head)
elif head in VOWELS:
return without_vowels(tail)
return [head, *without_vowels(tail)]
USAGE
>>> test = ["a", ["h", "e", "j"], ["t", "e", "s", "c", "o"]]
>>> without_vowels(test)
[['h', 'j'], ['t', 's', 'c']]
>>>