How to implement DFS with recursive function on JSON dict of tree? - python

I use a recursive Depth-First-Search function to traverse a tree where each node has an index.
During traversing, I need to assign one node (whose type is dict) to a variable to further process from outer scope.
It seems that I use a useless assignment. What is the most efficient way to do that?
def dfs(json_tree, index, result):
if json_tree['index'] == index:
result = json_tree['index'] ## not work!
return
if 'children' not in json_tree:
return
for c in json_tree['children']:
dfs(c, index, result)

Try returning result instead. Note that I changed your function signature. This will also short-circuit the search as soon as index is found.
def dfs(json_tree, index):
if json_tree['index'] == index:
return json_tree['index']
if 'children' not in json_tree:
return None
for c in json_tree['children']:
result = dfs(c, index)
if result is not None:
return result
return None
Edit: Updated with a final return path in case index is never found.

Related

How to get first satisfied return value for a collection?

I am new to Scala. I have a HashSet, when I iterate over it, I apply a recursive function to the element. How can I get the first satisfied function return value?
I tried collections.find(...).map(...), but cannot extract the return value inside the function in find(), and I don't want map to run these recursive function again.
def Rec(myObject, acc: list):
if myObject.size == 1:
return acc
elif len(myObject.myList) == 0:
return None
else:
for e in myObject.myList:
#func is another function that create a new object whose size is smaller and changes myList attribute
newObject = func(myObject, e)
acc.append(e)
res = Rec(newObject, acc)
if res:
return res
return None
So, my question is how to convert above python code to idiomatic scala code.
EDIT:
For example:
I want to write like this:
list.find(e=>Rec(e).isDefined).map(e=>Rec(e).get)
Rec() is a function that returns an option. And I want to extract the result of Rec(e) in find(...) when it finds, so I don't have to recalculate it in the map(...)
If I understand correctly, you have a List of elements of some (unspecified) type and you want to process each element only until the first non-None result.
Something like this?
myObject.myList //List of elements
.view //evaluate lazily
.flatMap(rec) //pass to the rec() func, flatten away all None results
.headOption //Some(<1st good result>) or None
In this case rec() is invoked only until the first non-None result is returned, or until the end of the list if no non-None result is produced.

Python: why contents of list are different inside and outside function?

I have a function doing binary tree traversal, and I have a global list "stack" to store temporary values.
stack = []
def search(root, v):
global stack
stack.append(root.info)
if root.info == v:
print(stack) #<------- THE FIRST PRINT IS HERE
return
if root.left is not None:
search(root.left, v)
if root.right is not None:
search(root.right, v)
stack.pop()
pass
def lca(root, v1, v2):
search(root,v1)
print(stack) #<------- THE SECOND PRINT IS HERE
Your Output (stdout)
[4, 2, 1]
[4]
input: v1=1, v2=7
When I print the value of the list from inside and outside the function, I found that the results are different -- when printed inside, the result is [4,2,1], and outside is [4]. I have tried different ways, such as creating the list outside the function, and then pass it to the function, the result is always the same. Can anyone know why this happened?
You seem to believe that after you hit the explicit return in your search function, your recursive search stops. But it doesn't. The search calls higher up the call stack will still go on triggering more searches, popping things off stack, altering its contents.
Perhaps you want something like this: use a return value to signal from search when it has successfully found the thing it was looking for, and don't search any more after that happens.
def search(root, v):
global stack
stack.append(root.info)
if root.info == v:
print(stack)
return True
if root.left is not None and search(root.left, v):
return True
if root.right is not None and search(root.right, v):
return True
stack.pop()
return False
This will prevent the stack being altered after the point where the value is found.

Return Inorder Traversal list

I'm trying to return list from inorder traversal and below is my code. If my input is [1,2,3] and output should be [3,1,2], but I'm returning value none. Can you please suggest what is wrong in my code? Thanks.
def inorderTraversal(currentNode,output=None):
if output==None:
output=[]
if currentNode.left:
return inorderTraversal(currentNode.left,output)
return output.append(currentNode.data)
if currentNode.right:
return inorderTraversal(currentNode.right,output)
The problem is this line:
return output.append(currentNode.data)
You are returning the value of append but that is None. append changes the list but it does not return the new value of the list. Do this instead.
output.append(currentNode.data)
return output

recursive sorting in python

I am trying to run a sorting function recursively in python. I have an empty list that starts everything but everytime I try to print the list I get an empty list. here is my code. Any help would be greatly appreciated
def parse(list):
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list)
The value of newParse is not preserved between invocations of the function; you're setting it equal to [] (well, you're creating a new variable with the value []).
Since the only time you return is
newParse = []
if len(list) == 0:
return newParse`
you will always be returning [] because that is the value of newParse at that time.
Because you are doing this recursively, you are calling the function anew, without keeping the function's own state. Take a moment to consider the implications of this on your code.
Instead of initialising newParse = [], add an optional parameter newParse defaulting to a bogus value, and set newParse = [] if you receive that bogus value for newParse. Otherwise, you'll actually be getting the same list every time (i.e. the contents of the list object are being mutated). And newParse through in your tail call.
You also seem to have the problem that your definition and and the supposedly-recursive call refer to different functions.
def sort(list, newParse = None):
if newParse is None:
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list, newParse)
Here is what I think you are trying to do:
def recursive_sort(a_list):
def helper_function(list_to_be_sorted, list_already_sorted):
new = []
if len(list_to_be_sorted) == 0:
return list_already_sorted
else:
x = min(list_to_be_sorted)
list_to_be_sorted.remove(x)
new.append(x)
return helper_function(list_to_be_sorted, list_already_sorted + new)
return helper_function(a_list, [])
You shouldn't name variables list, as that is a builtin.
Also, if you are trying to implement a recursive sort function, you might want to look at quicksort, which is a very common (and fast) recursive sorting algorithm. What you have tried to implement is a recursive version of selection sort, which is much slower.
Also, if you actually need a sorting function, rather than just wanting to implement a recursive one, you should use the list method sort, or the function on an iterable sorted, both of which will be a lot faster than anything you could make in Python.

Finding a node in a tree

I am having trouble finding a node in a tree with arbitrary branching factor. Each Node carries data and has zero or greater children. The search method is inside the Node class and
checks to see if that Node carries data and then checks all of that Nodes children. I keep ending up with infinite loops in my recursive method, any help?
def find(self, x):
_level = [self]
_nextlevel = []
if _level == []:
return None
else:
for node in _level:
if node.data is x:
return node
_nextlevel += node.children
_level = _nextlevel
return self.find(x) + _level
The find method is in the Node class and checks if data x is in the node the method is called from, then checks all of that nodes children. I keep getting an infinite loop, really stuck at this point any insight would be appreciated.
There are a few issues with this code. First, note that on line 2 you have _level = [self]. that means the if _level == [] on line 5 will always be false.
The 2nd issue is that your for loop goes over everything in _level, but, as noted above, that will always be [self] due to line 2.
The 3rd issue is the return statement. You have return self.find(x) + _level. That gets evaluated in 2 parts. First, call self.find(x), then concatenate what that returns with the contents of _level. But, when you call self.find(x) that will call the same method with the same arguments and that, in turn, will then hit the same return self.find(x) + _level line, which will call the same method again, and on and on forever.
A simple pattern for recursive searches is to use a generator. That makes it easy to pass up the answers to calling code without managing the state of the recursion yourself.
class Example(object):
def __init__(self, datum, *children):
self.Children = list(children) # < assumed to be of the same or duck-similar class
self.Datum = datum
def GetChildren(self):
for item in self.Children:
for subitem in item.GetChildren():
yield subitem
yield item
def FindInChildren(self, query): # where query is an expression that is true for desired data
for item in self.GetChildren():
if query(item):
yield item

Categories