5

我有一个循环给我三个变量

matteGroup
matteName
object

我想制作一个嵌套字典来保存所有数据,例如:

dictionary{matteGroup: {matteName: obj1, obj2, ob3} }

我正在一一检查对象,所以我想创建matteGroup如果它不存在,创建matteName如果它不存在,然后创建或附加对象的名称。我尝试了很多解决方案,如普通字典、defaultdict 和我在网上找到的一些自定义类,但我无法正确完成。我有一个很好的嵌套,我无法附加,反之亦然。

这是循环

    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)

有了这个,我分别得到了两个字典,但不是那么有用!有什么提示吗?

谢谢

4

5 回答 5

7

如果我正确理解了您的要求:

In [25]: from collections import defaultdict

In [26]: d = defaultdict(lambda: defaultdict(list))

In [30]: for group, name, obj in [('g1','n1','o1'),('g1','n2','o2'),('g1','n1','o3'),('g2','n1','o4')]:
   ....:     d[group][name].append(obj)
于 2012-01-09T13:52:40.563 回答
4

尝试这样的事情

dizGroup = {}

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] = {}

        if matteName not in dizGroup[matteGroup]:
            dizGroup[matteGroup][matteName] = []

        dizGroup[matteGroup][matteName].append(obj)
于 2012-01-09T13:50:26.863 回答
2

查看模块defaultdict中的。collections

这是一个简单的例子,看起来像你想要的:

>>> from collections import defaultdict
>>> dizGroup = defaultdict(lambda:defaultdict(list))
>>> dizGroup['group1']['name1'].append(1)
>>> dizGroup['group1']['name1'].append(2)
>>> dizGroup['group1']['name1'].append(3)
>>> dizGroup['group1']['name2'].append(4)
>>> dizGroup['group1']['name2'].append(5)
>>> dizGroup['group2']['name1'].append(6)
>>> dizGroup
defaultdict(<function <lambda> at 0x7ffcb5ace9b0>, {'group1': defaultdict(<type 'list'>, {'name2': [4, 5], 'name1': [1, 2, 3]}), 'group2': defaultdict(<type 'list'>, {'name1': [6]})})

所以,你应该只需要这个:

if mc.objExists(obj + ('.matteGroup')):
   matteGroup = mc.getAttr(obj + ('.matteGroup'))
   matteName = mc.getAttr(obj + ('.matteName'))
   dizGroup[matteGroup][matteName].append(obj)
于 2012-01-09T13:53:26.970 回答
1

如果速度是一个问题,您可以使用 try/except 子句来尝试首先填充您的数据,而不是检查项目是否存在,然后每次通过循环添加它

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]

对于第一次尝试/例外,如果节点上不存在 attr (现在没有打开 Maya,所以我不能把它放入......),最好放置任何异常 Maya 抛出。这基本上检查 attr 并继续到下一个 obj 如果 attr 不存在。您可以将它们都放在那里,而不是每个都有自己的 try/except,因为如果其中任何一个都不存在,它应该会出错。

第二次尝试/除检查 matteGroup 是否在您的字典的顶层。如果不是,那么您知道 matteName 和 obj 列表也不在您的数据结构中,因此它会添加它们并继续到下一个 obj

第三个 try/except 尝试将 obj 附加到 matteName dict 项目的列表中。如果您在此处收到 keyError,则表示 matteName 不在您的 matteGroup 字典中,因此它会添加它并创建列表,其中当前 obj 作为该列表中的第一项。

因此,就速度而言,只要数据结构中存在项目,您添加到该数据项目的下一个 obj 基本上只会被添加,而无需在添加之前测试所有其他数据结构是否到位,让你的循环走得更快,你走得越远(假设有很多节点共享 matteGroups 和/或 matteNames)

于 2017-06-11T03:33:55.030 回答
0

由于腌制我的对象的问题,使用了以前的一些答案,我也试图解决这个问题。这对我来说是动态添加新键到两个不同子级别的字典的方法:

from collections import defaultdict
test = defaultdict(defaultdict)
test["level1"]["level2"] = 1
test["level1"]["level2_second"] = 2
print(test)

defaultdict(, {'level1': defaultdict(None, {'level2': 1, 'level2_second': 2})})

这个解决方案似乎只能处理两层嵌套。

于 2018-10-30T17:28:47.503 回答