Recursion (2)

In this lecture, we will continue with more examples of recursion.

Review: sumList

Let us consider a simple example of an iterative vs recursive approach to the same problem.

def sumListIterative(numList):
    """Returns sum of given list numList"""
    sum = 0
    for num in numList:
        sum += num
    return sum
sumListIterative([3, 4, 20, 12, 2, 20])
61
def sumList(numList):
    """Returns sum of given list numList"""
    if numList == []: 
        return 0
    else:
        return numList[0] + sumList(numList[1:])
sumList([3, 4, 20, 12, 2, 20])
61

Finding Files On Our Computer

This task will help us understand some of the key differences and advantages that recursion might offer over writing iterative programs. Ultimately, we’re aiming to write an iterative and recursive version of a program that takes in a nested list of lists (the nesting could go on arbitrarily) corresponding to files and folders within folders on a computer and returns whether a file we’re looking for is in the nested list or not.

But first we’ll write a simpler version of the program to get started.

Finding Files In A List

Let’s first write an iterative and recursive function for finding a file from a single list of file names.

def fileFoundIterative(files, target):
    """
    Iterative function that returns True if the list of files
    contains the target file and False otherwise.
    """
    
    for file in files:
        if file == target:
            return True
    return False

files = ["homework", "puppy", "films"]
print(fileFoundIterative(files, "puppy"))
print(fileFoundIterative(files, "kitten"))
True
False
def fileFound(files, target):
    """
    Recursive function that returns True if the list of files
    contains the target file and False otherwise.
    """
    
    if files == []:
        return False
    else:
        return files[0] == target or fileFound(files[1:], target)

files = ["homework", "puppy", "films"]
print(fileFound(files, "puppy"))
print(fileFound(files, "kitten"))
True
False

Finding Files From Nested Lists

We now look at the general task of finding files when we have folders within folders and compare the iterative and recursive approaches.

def fileFoundIterative(folder, target):
    """
    Iterative function that returns True if the folder
    (nested list) contains the target file and False otherwise.
    """
    
    # create an initial list or pile of files/folders to look through
    pile = [item for item in folder]

    # keep looking while the pile isn't empty
    while len(pile) > 0:
        
        # get and remove the last item from the pile
        # we can use the pop() list method for this
        item = pile.pop()
        
        # if the item is a folder (list) add each item
        # inside the folder onto the pile
        if type(item) == list:
            for obj in item:
                pile.append(obj)
        
        # otherwise check if the current file is our target
        elif item == target:
            return True

    return False

nestedFolders = ["homework", ["cat", "puppy", "goat"], ["films", "books"]]
print(fileFoundIterative(nestedFolders, "puppy"))
print(fileFoundIterative(nestedFolders, "poems"))
True
False
def fileFound(folder, target):
    """
    Recursive function that returns True if the folder
    (nested list) contains the target file and False otherwise.
    """
    # base case
    if folder == []:
        return False
    else:
        firstItem = folder[0]
        
        # check if the first item is itself a folder (list), if so, recurse
        if type(firstItem) == list and firstItem != []:
            return fileFound(firstItem, target)
        
        # otherwise we know the item is a file name, so we check if this
        # is our target, or if the remaining files/folders contain our target
        return firstItem == target or fileFound(folder[1:], target)

nestedFolders = ["homework", ["cat", "puppy", "goat"], ["films", "books"]]
print(fileFound(nestedFolders, "puppy"))
print(fileFound(nestedFolders, "poems"))
True
False