Mercurial > hg > MPIWGWeb
diff HashTree.py @ 48:f59bdd5f4890
Merge with 5c6ad316e1ceef48e323907ab81dd50e7ef743b2
| author | dwinter |
|---|---|
| date | Mon, 29 Apr 2013 16:02:24 +0200 |
| parents | 196db636a8fd |
| children | 1ed79b33200c |
line wrap: on
line diff
--- a/HashTree.py Mon Apr 29 16:01:24 2013 +0200 +++ b/HashTree.py Mon Apr 29 16:02:24 2013 +0200 @@ -44,10 +44,7 @@ else: sub = [self.value] - keys = self.children.keys() - keys.sort() - for k in keys: - #logging.debug("getSubtreeList: k=%s sub=%s"%(k,sub)) + for k in sorted(self.children.keys()): sub.extend(self.children.get(k).getSubtreeAsList()) return sub @@ -59,29 +56,55 @@ return "(%s:%s)"%(self.key, self.value) else: sub = "(%s:%s):["%(self.key, self.value) - keys = self.children.keys() - keys.sort() - for k in keys: + for k in sorted(self.children.keys()): sub += self.children.get(k).getSubtreeAsText() sub += ", " return sub + "] " + + class HashTree: """Tree using dictionaries""" + # root HashTreeNode root = None + # separator by which key strings are split into parts keySeparator = '.' + # function applied to key parts keyFn = None def __init__(self, keySeparator='.', keyFn=None): - """creates a HashTree""" + """creates a HashTree. + + @param keySeparator string by which key strings are split into parts + @param keyFn function applied to key parts (e.g. int if key parts are numbers) + """ self.root = HashTreeNode() self.keySeparator = keySeparator self.keyFn = keyFn + def _splitkey(self, key): + """returns a list of key parts""" + if isinstance(key, basestring): + # its a string - split + keys = key.split(self.keySeparator) + if self.keyFn is not None: + keys = [self.keyFn(k) for k in keys] + + elif isinstance(key, list): + # its a list - keep + keys = key + + else: + # not a list - wrap in list + keys = [key] + + return keys + + def getNode(self, key): """gets node under key from the tree. key can be sequence of key string or a single string using keySeparator. @@ -90,22 +113,11 @@ if key is None: return self.root - if isinstance(key, basestring): - keys = key.split(self.keySeparator) - if self.keyFn is not None: - keys = [self.keyFn(k) for k in keys] - - elif isinstance(key, list): - keys = key - - else: - keys = [key] + keys = self._splitkey(key) node = self.root for k in keys: - #logging.debug("getNode node=%s k=%s"%(node, repr(k))) node = node.getNode(k) - #logging.debug("getNode got:%s"%(node)) if node is None: return None @@ -127,16 +139,7 @@ """adds value under key to the tree. key can be sequence of key string or a single string using keySeparator. """ - #logging.debug("add(key=%s, value=%s)"%(repr(key), value)) - if isinstance(key, basestring): - keys = key.split(self.keySeparator) - if self.keyFn is not None: - keys = [self.keyFn(k) for k in keys] - elif isinstance(key, list): - keys = key - else: - keys = [key] - + keys = self._splitkey(key) node = self.root for k in keys: nextnode = node.getNode(k) @@ -147,6 +150,34 @@ node = nextnode node.value = value + - + def getChildrenOf(self, key): + """returns the list of child (values) of the node under key.""" + node = self.getNode(key) + if node.children is None: + return [] + else: + # sort children by key + childlist = sorted(node.children.items(), key=lambda x:x[0]) + # and return the values + return [n.value for (k, n) in childlist if n.value is not None] + + + def getAncestorsOf(self, key): + """returns the list of ancestor (values) of the node under key. + ordered from root up.""" + keys = self._splitkey(key) + node = self.root + ancestors = [] + for k in keys: + if node.value is not None: + ancestors.append(node.value) + + node = node.getNode(k) + if node is None: + return ancestors + + return ancestors +
