I had to solve a trivial problem for school using A* (which isn't what I was having trouble with) and I wanted to use a tree to store the explored nodes so when a solution was found it would be easy to find a path from the leaf back to the root.
In python a tree can be made by using defaultdictionaries:
def tree(): return defaultdict(tree)
so for example:
a=tree() is an empty tree
a[1] tree with one root node
a[1][2] has a child of 2
a[1][2]['another']... and so on.
And I tried to make something to add a new node given an arbitrary node (k) given the tree (a) and desired new node. I could only figure it out using recursion.
def addNode(a,k,newNode):
for x in list(a.keys()):
if x!=k:
a[addNode(a[x],k,newNode)]
if x==k:
a[x][newNode]
break
But I don't understand recursion too well, not enough to do it right; this ends up adding new nodes with proper parents yet adds None nodes. So here's another example:
a=tree()
a
defaultdict(<function tree at 0x029CE930>, {})
a[1]
defaultdict(<function tree at 0x029CE930>, {})
a[1][2]
defaultdict(<function tree at 0x029CE930>, {})
a[1][3]
defaultdict(<function tree at 0x029CE930>, {})
a[1][2]['b']
defaultdict(<function tree at 0x029CE930>, {})
addNode(a,'b','new')
a
defaultdict(<function tree at 0x029CE930>, {1: defaultdict(<function tree at 0x029CE930>, {2: defaultdict(<function tree at 0x029CE930>, {'b': defaultdict(<function tree at 0x029CE930>, {'new': defaultdict(<function tree at 0x029CE930>, {})})}), 3: defaultdict(<function tree at 0x029CE930>, {}), None: defaultdict(<function tree at 0x029CE930>, {})}), None: defaultdict(<function tree at 0x029CE930>, {})})
How do I implement this properly and why is the addNode procedure making these None nodes? I kind of see that I have to exit the recursion properly so how is that done?
Also I tried to recover the path as follows:
parentList=[]
found=False
def getPath(tree,final):
global found
for x in list(tree.keys()):
parentList.append(x)
if found:
parentList.pop()
if x==final:
found=True
else:
getPath(tree[x],final)
if not found:
parentList.pop()
I tried to add all the parents onto a stack until the goal node is found and then pop off all the parents until only the path that got to the goal state remains on the stack. How could I do this in an elegant way?
You are seeing None
added because your addNode
function doesn't return anything. This means that when you do the recursive call using a[addNode(a[x],k,newNode)]
it is the equivalent of addNode(a[x],k,newNode); a[None]
addNode(a[x],k,newNode); a[None]
. I think you actually want something like the following:
def addNode(a,k,newNode):
if k in a:
a[k][newNode]
else:
for x in a:
addNode(a[x],k,newNode)
For example:
>>> import json
>>> a = tree()
>>> a['1']
defaultdict(<function <lambda> at 0x7fee0285f848>, {})
>>> addNode(a, '1', 'new')
>>> print json.dumps(a)
{"1": {"new": {}}}
>>> a['1']['2']['3']
defaultdict(<function <lambda> at 0x7fee0285f848>, {})
>>> addNode(a, '3', 'new2')
>>> print json.dumps(a)
{"1": {"new": {}, "2": {"3": {"new2": {}}}}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.