Case 1:
Here, you are passing a list object having zero elements, as argument to the "root invocation" of printPath().
Inside this invocation, that empty list can be accessed with the parameter called path.
During the execution of the function, that empty list would become non-empty.
But once you've exited this "root invocation" of the function, that parameter called path, which is referring to the (now non-empty) list, goes out of scope.
Now, you are left with no other variable (or name) referring to that non-empty list, so there is no way for you to actually look at the non-empty path and celebrate.
Case 2:
Here also, you are passing an empty list object to your "root invocation" of printPath(). But the difference is that even before you invoke printPath(), you have ensured that there is one more variable (or name) called p_, which is pointing to the same empty list object that you are passing to the "root invocation". As with Case 1, inside the invocation, the empty list object is accessed with the parameter name path. As with Case 1, this empty list will become non-empty during the execution. As with Case 1, when the root invocation eventually completes execution and returns control, the parameter named path which was pointing to the (now non-empty) list object, will go out of scope, but you are still left with one more variable called p_, pointing to the same (now non-empty) list object.
Reason why print self.printPath(root, 5, p_) prints None:
Let's take a simple tree, in which the root node has a value of 0, and the left child has a value of 5. Assume that there are no other nodes in the tree.
What happens in your root invocation of printPath():
You will first check if root.val == node. The test will fail.
You will next check if root.left. The test will pass. You will enter that if block, append 0 to path, and make your second invocation of printPath(). Now, carefully note the fact that the second invocation is made from within the first invocation. The first invocation has not yet completed. In fact, at that instant, the first invocation as well as the second invocation are both in a state of having partially executed. Correct? And the first invocation and second invocation at two different line numbers. The first invocation is at the line where printPath() is invoked for the left child, and the first invocation is just about to start executing at the first line of printPath(). Correct?
What happens next?
The second invocation also checks if root.val == node. This time, the test succeeds, and it enters the if block, appends 5 to path, and returns path.
But where does this returned value go? To the place where this second invocation happened ! Which, if you remember, is another line in printPath(). At that line, you are invoking printPath(), but not capturing its return value in any variable -- you are just ignoring its return value. So, the 0 5 string returned by the second invocation is being ignored. The execution of the first invocation continues until it reaches the last line of printPath(). At the last line, there is no other return statement. So, in the absence of an explicit return statement, any Python function will return None. So, this first invocation will return None, to the place where your first invocation happened (I think that is in lowest_main()).
The first invocation is printing this None value.
How to correct:
To correct this, please change the following line:
self.printPath(root.left, node, path)
to this:
return self.printPath(root.left, node, path)
Similarly, please change the following line:
self.printPath(root.right, node, path)
to this:
return self.printPath(root.right, node, path)
printPathfunction you have included:selfis not the leading argument, so you should useprintPathinstead ofself.printPath. Second is that if you are trying to assignreswith results ofprintPath, as implemented,printPathdoes not return a list or any value thusreswill always equal toNone. Yes you can append nodes (or whatever) topaththat is provided, and yes the same assignment will get passed as you have specified in the code you have included.p_ = []; print self.printPath(root, 5, p_)if I print the path within the return blockif root.val == node: path.append(node);print path;return path, I can see the correct path. do you have any idea why this is happening?return pathstatement. However, the results of the recursiveprintPathisn't being returned which means that invocations using a root and node that are not equal will not have a return value. This is where I was confused about when I thought your code did not have areturnstatement.