If speed is a concern, you can use try / except clauses to just try to populate your data first, rather than checking if elements exist, then adding them every time through the loop
diz = {} for obj in mc.ls(type='transform'): try: matteGroup = mc.getAttr('%s.matteGroup' %obj) matteName = mc.getAttr('%s.matteName' %obj) except Exception: continue try: diz[matteGroup] except KeyError: diz[matteGroup] = {matteName : [obj]} continue try: diz[matteGroup][matteName].append(obj) except KeyError: diz[matteGroup][matteName] = [obj]
for the first attempt / with the exception, it would be better to throw any maya exception if attr does not exist on node (now Maya does not open for me, so I could not put this in ...). This essentially checks attr and continues to the next obj if attr does not exist. You can put them both there, and not each of them has its own try / except, because this should be a mistake if either does not exist.
the second try / except checks if the matte group is at the top level of your dict. If this is not the case, then you know the name matteName, and the obj list is also not in your data structure, so it adds them and continues until the next obj
third attempt / excludes an attempt to add obj to the matteName dict list of elements. If you get keyError here, it means that matteName is not in your matteGroup dict, so it adds it and creates a list with the current obj as the first element in this list.
So, as far as speed is concerned, there are any time elements in your data structure, the next object added to this data element is essentially just added without checking if all other data structure is in place before adding it, making your cycle move faster into the cycle which you are going to (provided that many nodes share matte groups and / or matte names)
source share