IMHO, parsing the string is just a matter of administrative logic and
should not be bothered with when focussing on the business logic (which, in
this case, is recreating the hierarchy).

Sure JSON, YAML, and XML(ugly) are a few options to choose from for parsing
the string. In the end, It is just a detail to get the data, nothing more,
nothing less.

What is important is how we deal with that data in the most efficient,
optimized and readable way.

So here is my implementation, parsing your original indented string. This
definitely covers your points 1 and 2.  3 is a matter of opinion and is

Few things to note:

   - Right in the beginning, we parse the string in a single line, keeping
   the administrative logic out from the rest of our business code. You can
   easily replace this single line with whatever parser you want.

   - I am using `namedtuple` for readability they are lightweight and
   require no more memory than regular tuples.

   - `bisect` uses a basic bisection algorithm, an improvement over the
   common approach for finding an insertion point in a sorted list without
   having to sort it again.

   - This completely eliminates multiple calls to parent() as in your
   original implementation. For each line in the input string, we parent only
   once, no need to go back up or down in the hierarchy with multiple
   if-elif-else. This is more efficient and straight forward.

   - Handles multiple hierarchies starting from the root (which your
   version also covered I think)

   - Space characters are not a problem on an empty line(In my example, I
   have deliberate space chars to demonstrate that). On that note, please note
   that I am using line.strip(' ') instead of line.strip(), the reason being
   you can still parse escape characters like \r \t \n etc., strip() eats them
   up as they are whitespaces as well.


from collections import namedtuplefrom bisect import bisect_left
import pymel.core as pm

def hierarchy_from_string(hierarchy):
    NodeInfo = namedtuple('NodeInfo', 'node indent')
    nodeInfos = []
    for nodeName, currIndent in ((line.strip(' '),
                                  len(line) - len(line.lstrip(' ')))
                                 for line in hierarchy.split("\n")
                                 if line.strip()):

        node = ([0] if
                else pm.createNode('transform', name=nodeName))

        parentIndex = bisect_left([nodeInfo.indent for nodeInfo in nodeInfos],

        parentNode = (nodeInfos[parentIndex - 1].node
                      if parentIndex - 1 >= 0 else None)

        nodeInfo = NodeInfo(node=node, indent=currIndent)

        if parentIndex < len(nodeInfos):
            nodeInfos[parentIndex] = nodeInfo

        pm.parent(node, parentNode)

hierarchy_from_string("""\rig    implementation        geometry
skeleton    interface        controls        previewfoo    bar
   baz                     alice            bob""")

- Alok

You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
To view this discussion on the web visit
For more options, visit

Reply via email to