1

This is the coding problem I'm doing right now in Python3:

class TreeNode:
  def __init__(self, val, left=None, right=None):
    self.val = val
    self.left = left
    self.right = right

def find_paths(root, targetSum):
  allPaths = []
  dfs(root, targetSum, [], allPaths)
  return allPaths
  
def dfs(node, targetSum, currentPath, result):
  
  if not node:
    return
  
  currentPath.append(node.val)

  if node.val == targetSum:
    if not node.left and not node.right:
      result.append(list(currentPath))
  else:
    dfs(node.left, targetSum - node.val, currentPath, result)
    dfs(node.right, targetSum - node.val, currentPath, result)

  # backtrack here
  del currentPath[-1]


def main():

  root = TreeNode(12)
  root.left = TreeNode(7)
  root.right = TreeNode(1)
  root.left.left = TreeNode(4)
  root.right.left = TreeNode(10)
  root.right.right = TreeNode(5)
  required_sum = 23
  print(find_paths(root, required_sum))


main()

The question is this line right here:

      result.append(list(currentPath))

it prints out:

[[12, 7, 4], [12, 1, 10]]

but if you put:

      result.append(currentPath)

it will print out:

[[], []]

I tried printing out the type of "currentPath" and it is already a list. Why is the list() necessary when it's already of type list?

user2926999
  • 393
  • 1
  • 3
  • 11

2 Answers2

3

Because of this:

del currentPath[-1]

In other words: you are adding the currentPath object to your result object, but then you later modify it. The modification is reflected in your result. Using list(…) makes a copy of the list.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
1

In your case, if you do

result.append(currentPath)

then you appending the object currentPath. This, effectively, you can think of it as appending a pointer to the object currentPath. Meaning that the result will actually hold the currentPath and not the contents of the currentPath.

Thus, when you will do

del currentPath[-1]

you will alter the currentPath object. Since the result has the actual currentPath, then the result will also be modified.

BUT!

When you are doing

result.append(list(currentPath))

you are appending a new object, having the contents of the currentPath. This results to result having a different object in it, and not the actual currentPath. This is because the list() will create a new list, from the contents of the currentPath.

Thus, when you are modifying the contents of the currentPath with the

del currentPath[-1]

the result will not be modified.


To verify it your self, you can check the

id(result[0])
id(currentPath)

when using the .append(list(currentPath)) and when using the .append(currentPath).

Xxxo
  • 1,784
  • 1
  • 15
  • 24