Terry Reedy <[EMAIL PROTECTED]> writes: > Bart Kastermans wrote: >> I am playing with some trees. In one of the procedures I wrote >> for this I am trying to change self to a different tree. A tree >> here has four members (val/type/left/right). I found that self = SS >> does not work; I have to write self.val = SS.val and the same for >> the other members (as shown below). Is there a better way to do this? >> >> In the below self is part of a parse tree, F is the parse tree of a >> function f with argument x. If a node in the parse tree is labelled >> f, we should replace it by the parse tree for the function f, F, with >> the remainder of the tree substituted for the input variable for the >> function f, here x. >> >> def elimF (self): >> if self.val == "f": >> SS = F.copy () >> SS.subst ('x', self.left) >> self.val = SS.val # from here: set self to be SS >> self.type = SS.type >> self.left = SS.left >> self.right = SS.right # completed: set self to be SS > > If you examine nodes from their parent, I believe you can do the > substitution in one step. Something like: > > for slot,child in ( ('left',self.left), ('right',self.right) ): > if child is not None: > if child.val == 'f': > setattr(self, slot, F.copy().subst('x', child.left)) > child.elimF > > where .subst returns the modified tree.
That worked very well. The option that looks even better to me was just to build a copy (the exceptional case of the root of the tree that is needed bugged me a bit). Then self does not have to be changed at all. Your use of setattr made me find getattr, and this allowed for a quite smooth (I think) implementation. def elimF (self): """ do the substitution of all nodes labelled f. """ if self.val == "f": ret_val = F.subst ('x', self.left) ret_val.left = NoneOr (ret_val.left, 'elimF') ret_val.right = NoneOr (ret_val.right, 'elimF') return ret_val else: return Tree (self.val, self.type, \ NoneOr (self.left, 'elimF'), \ NoneOr (self.right, 'elimF') ) This uses the function: def NoneOr (tree, mem_function, *arguments): """ if tree is not None then tree.mem_function (arguments). """ if tree == None: return None else: return getattr (tree, mem_function) (*arguments) Bart -- http://mail.python.org/mailman/listinfo/python-list