I have a loop giving me three variables
matteGroup
matteName
object
I would like to make a nested dicionary holding all the data like:
dictionary{matteGroup: {matteName: obj1, obj2, ob3} }
I am checking the objects one by one so I would like to create the matteGroup
if it doesn't exist, create the matteName
if it doesn't exixst and then create or append the name of the object.
I tryed a lot of solution like normal dictionaries, defaultdict and some custom classes I found on the net, but I haven't been able to do it properly. I have a nice nesting I am not able to append, or vice versa.
This is the loop
dizGroup = {}
dizName = {}
for obj in mc.ls(type='transform'):
if mc.objExists(obj + ('.matteGroup')):
matteGroup = mc.getAttr(obj + ('.matteGroup'))
matteName = mc.getAttr(obj + ('.matteName'))
if matteGroup not in dizGroup:
dizGroup[matteGroup] = list()
dizGroup[matteGroup].append(matteName)
if matteName not in dizName:
dizName[matteName] = list()
dizName[matteName].append(obj)
with this I get the two dictionaries separately, but is not so useful! Any hint?
Thanks
Due to an issue with pickling my object, that used some of the previous answers, I tried to solve this as well. This is what worked for me for dynamically adding new keys to two different sub levels of dictionaries:
This solution seems to be only able to handle two levels of nesting.
try something like this
Provided I've understood your requirements correctly:
if speed is a concern, you could utilize try/except clauses to just try to populate your data first rather than checking if items exist and then adding it each time through the loop
for the first try/except, it would be best to put whatever exception maya throws if an attr doesn't exist on a node (don't have maya open right now, so I couldn't put that in...). This essentially checks for the attr and continues to the next obj if the attr isn't there. You can put them both in there instead of each having their own try/except, because it should error if either doesn't exist anyway.
the second try/except is checking if the matteGroup is in the top level of your dict. If it isn't, then you know the matteName and list of obj's isn't in your data structure either, so it adds them and continues to the next obj
the third try/except tries to append the obj to the matteName dict item's list. If you get a keyError here, it means that the matteName isn't in your matteGroup dict, so it then adds it and creates the list with the current obj as the first item in that list.
So, as far as speed is concerned, any time items exist in your data structure, the next obj you add to that data item will essentially just get added without having to test if all of the other data structure is in place before adding it, making your loop go faster the further into the loop you go (provided there are a lot of nodes sharing matteGroups and/or matteNames)
Look at the
defaultdict
in thecollections
module.Here's a simple example that looks like what you're going for:
So, you should just need this: