Serialize and deserialize a tree
Your printTree function is unnecessarily long.

Also, I really don't like the output of your serialize. I was not able to parse (as a human) this back into the structure of the tree. For me it would be much better if the structure was apparent from the serialization.

Therefore I rewrote your code in the following way:

class Node:

    def __init__(self, value='#', children=None):
        self.value = value
        self.children = children if children else []

    def __nonzero__(self):
        return self.value != '#'

    def __eq__(self, other):
        return self.value == other.value and self.children == other.children

    def __str__(self):
        buf, out = [self], []
        while buf:
            # current level
            out.append(", ".join(str(node.value) for node in buf))
            if any(node for node in buf):
                # add children
                buf = [subnode if subnode else Node()
                       for node in buf
                       for subnode in node.children]
            else:
                break
        return "\n".join(out)

    def __repr__(self):
        if not self:
            return "Node()"
        children_repr = ",".join(repr(child) for child in self.children)
        return "Node({.value},[{}])".format(self, children_repr)

    def serialize(self):
        return repr(self).replace("Node", "").replace("()", "#")

    @staticmethod
    def deserialize(source):
        return eval(source.replace("#", "()").replace("(", "Node("))


if __name__ == "__main__":
    root = Node(1, [Node(2, [Node(4)]), Node(3, [Node(5), Node(6)])])
    print repr(root)
    print root
    source = root.serialize()
    root2 = Node.deserialize(source)
    print repr(root2)
    print root2
    assert root == root2


This class has the nice feature, that eval(repr(root)) is a copy of root, so repr(root) is a serialization of root.

The output of repr(root) is a bit verbose, though:

Node(1,[Node(2,[Node(4,[])]),Node(3,[Node(5,[]),Node(6,[])])])


Therefore I defined a serialize function, which just gets rid of all the Nodes. The deserialize function just puts them back in and does an eval.

Note that I used a different tree here than you. Here would be your structure:

root = Node(0, [Node(1, [Node(3, [Node(), Node(), Node()]),
                         Node(4, [Node(), Node(), Node()]),
                         Node(5, [Node(), Node(), Node()])]),
                Node(2, [Node(6, [Node(), Node(), Node()]),
                         Node(7, [Node(), Node(), Node()]),
                         Node(8, [Node(), Node(), Node()])]),
                Node()])


Or, even better to visualize:

root = Node(0, [Node(1, [Node(3, [Node(),
                                  Node(),
                                  Node()]),
                         Node(4, [Node(),
                                  Node(),
                                  Node()]),
                         Node(5, [Node(),
                                  Node(),
                                  Node()])]),
                Node(2, [Node(6, [Node(),
                                  Node(),
                                  Node()]),
                         Node(7, [Node(),
                                  Node(),
                                  Node()]),
                         Node(8, [Node(),
                                  Node(),
                                  Node()])]),
                Node()])


Example:

&gt;&gt;&gt; root.serialize()
'(0,[(1,[(3,[#,#,#]),(4,[#,#,#]),(5,[#,#,#])]),(2,[(6,[#,#,#]),(7,[#,#,#]),(8,[#,#,#])]),#])'


This could be cut down even further, but at this point it becomes a balance between the processing time needed to make this string smaller and the gain in memory from that.

With this function it could become:

def serialize2(self):
    replacements = [("Node", ""), ("()", "#"),
                    ("(", ""), (")", ""), (",[", "["), (",", "")]
    out = repr(self)
    for replacement in replacements:
        out = out.replace(*replacement)
    return out

&gt;&gt;&gt; root.serialize2()
'0[1[3[###]4[###]5[###]]2[6[###]7[###]8[###]]#]'


But this becomes hard to parse back into the tree and would break the setup of using __repr__ and eval. It would be possible using some fancy regular expressions, though.