2
\$\begingroup\$

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?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

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
\$\endgroup\$
0
1
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jun 26, 2013 at 3:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.