0

Since Python allows nested functions, we can write code like the following:

def solve_knapsack(profits, weights, capacity):       
    def knapsack_recursive(profits, weights, capacity, currentIndex):
        # base checks
        if capacity <= 0 or currentIndex >= len(profits):
          return 0
      
        # recursive call after choosing the element at the currentIndex
        # if the weight of the element at currentIndex exceeds the capacity, we  shouldn't process this
        profit1 = 0
        if weights[currentIndex] <= capacity:
          profit1 = profits[currentIndex] + knapsack_recursive(
            profits, weights, capacity - weights[currentIndex], currentIndex + 1)
      
        # recursive call after excluding the element at the currentIndex
        profit2 = knapsack_recursive(profits, weights, capacity, currentIndex + 1)
      
        return max(profit1, profit2)
    return knapsack_recursive(profits, weights, capacity, 0)

(If you're curious, this is the brute-force recursive solution for the Knapsack problem).

Notice that profits and weights are not mutated anytime in the nested function, but still they are passed to every recursive call. This is a pattern I've seen often, and makes sense for languages that do not allow nesting of functions, so everything needed by the function has to be passed in as arguments.

However, for Python though, the function knapsack_recursive has access to the arguments to solve_knapsack, so we can remove profits and weights from the formal parameters of the former, and the code would work just fine.

Is there a reason to choose one over the other?

2 Answers 2

1

As the previous poster indicated, you did not include a nested function. I think you intended knapsack_recursive to be a nested function, and were wondering about whether to pass profits and weights as arguments.

This is a matter of judgement. If this were my code, I wouldn't pass them as arguments, especially since these are unchanged throughout the calculation. But there is no right or wrong here.

Sign up to request clarification or add additional context in comments.

1 Comment

"you intended knapsack_recursive to be a nested function" - yes, fixed indentation now.
0

The code you posted does not contain any nested functions. It will not work without passing down the arguments to "knapsack_recursive". A function does not contain any information about a scope in which it will be called so the interpreter will throw a NameError if you try to use names that are not accessible in function definition. You would need to define "knapsack_recursive" in "solve_knapsack" in order for it to capture your arguments passed to "solve_knapsack". You may want to read more about nested functions for further explaination. For example here: https://www.programiz.com/python-programming/closure#:~:text=A%20function%20defined%20inside%20another,in%20order%20to%20modify%20them.

2 Comments

I think the poster intended to make knapsack_recursive a nested function.
Fixed! Not an uncommon mistake with a language that uses indentation for scope. Now you can answer the question asked.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.