# I'm practicing turning for loops into recursive functions. what do you think?

I am trying to turn this function:

collection = ['hey', 5, 'd']
for x in collection:
print(x)


Into this one:

def printElement(inputlist):
newlist=inputlist
if len(newlist)==0:
Element=newlist[:]
return Element
else:
removedElement=newlist[len(inputlist)-1]
newlist=newlist[:len(inputlist)-1]
Element=printElement(newlist)
print(removedElement)

collection = ['hey', 5, 'd']

printElement(collection)


It works, but I wonder if it's okay there's no "return" line under "else:" Is this as "clean" as I can make it? Is it better code with or without the newlist?

but I wonder if it's okay there's no "return" line under "else:"

Yes, that's OK. You don't need to return anything from your function if you don't want to. In fact, in the interest of consistency, you may as well remove the thing returned in the if block too:

def printElement(inputlist):
newlist=inputlist
if len(newlist)==0:
return
else:
removedElement=newlist[len(inputlist)-1]
newlist=newlist[:len(inputlist)-1]
Element=printElement(newlist)
print(removedElement)

collection = ['hey', 5, 'd']

printElement(collection)


Is it better code with or without the newlist?

Assigning new things to inputlist won't modify it outside of the function, so there's no harm in doing so. May as well get rid of newlist.

def printElement(inputlist):
if len(inputlist)==0:
return
else:
removedElement=inputlist[len(inputlist)-1]
inputlist=inputlist[:len(inputlist)-1]
Element=printElement(inputlist)
print(removedElement)

collection = ['hey', 5, 'd']

printElement(collection)


you don't use Element after assigning it, so you may as well not assign it at all.

def printElement(inputlist):
if len(inputlist)==0:
return
else:
removedElement=inputlist[len(inputlist)-1]
inputlist=inputlist[:len(inputlist)-1]
printElement(inputlist)
print(removedElement)

collection = ['hey', 5, 'd']

printElement(collection)


You don't really need to modify inputlist, since you only use it once after modifying it. Just stick that expression straight into the printElement call. And now that inputlist is never modified, you can get rid of removedElement too, and just inline its expression in the print function.

def printElement(inputlist):
if len(inputlist)==0:
return
else:
printElement(inputlist[:len(inputlist)-1])
print(inputlist[len(inputlist)-1])

collection = ['hey', 5, 'd']

printElement(collection)


Fun fact: for any list x, x[len(x)-1] can be shortened to x[-1]. Same with x[:len(x)-1] to x[:-1].

def printElement(inputlist):
if len(inputlist)==0:
return
else:
printElement(inputlist[:-1])
print(inputlist[-1])

collection = ['hey', 5, 'd']

printElement(collection)


Since the first block unconditionally returns, you could remove the else and just put that code at the function level, without changing the code's behavior. Some people find this less easy to read. Personally, I like my code to have the least amount of indentation possible.

def printElement(inputlist):
if len(inputlist)==0:
return
printElement(inputlist[:-1])
print(inputlist[-1])

collection = ['hey', 5, 'd']

printElement(collection)


That's about as compact as you can get, with a recursive solution. You should probably just stick with the iterative version, for a few reasons:

• Fewer lines
• More easily understood
• Doesn't raise a "maximum recursion depth exceeded" exception on lists with 200+ elements

Your function is needlessly complicated. The return value is never used. You also print from the end of the list, which is a bit odd: tail recursion is a more usual style. For example:

def printCollection(c):
if c:
print c[0]
printCollection(c[1:])


This still has the flaw that it copies the list for every element in the list, making it an O(n^2) function. It's also limited to data structures that use slices and indices. Here's a recursive version that prints any iterable:

def printCollection(c):
it = iter(c)
try:
el = it.next()
print el
printCollection(it)
except StopIteration:
pass


It's still a bit odd to recurse here as this is a naturally iterative problem.

• You're right. I was thinking I could get a better grip on recursion by doing some programs that were easier to understand. While that helped a little, I see I need to step it up. – user1604149 Jun 26 '13 at 3:03