如何制作嵌套字典并动态追加数据

Posted

技术标签:

【中文标题】如何制作嵌套字典并动态追加数据【英文标题】:How to make a nested dictionary and dynamically append data 【发布时间】:2012-02-06 00:55:31 【问题描述】:

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

matteGroup
matteName
object

我想制作一个包含所有数据的嵌套字典,例如:

dictionarymatteGroup: 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)

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

谢谢

【问题讨论】:

【参考方案1】:

试试这样的

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)

【讨论】:

【参考方案2】:

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

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)

【讨论】:

【参考方案3】:

查看collections 模块中的defaultdict

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

>>> 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)

【讨论】:

【参考方案4】:

如果速度是一个问题,您可以使用 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,因为如果其中任何一个都不存在,它应该会出错。

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

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

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

【讨论】:

您也可以组合最后两个 try/except 子句,然后尝试先将 obj 附加到列表中...不过确实有点困难,因为您不知道哪个 dict不包含您要访问的密钥,因此如果您真的想要,您必须使用嵌套的 try/except 子句来解释这一点...... aaaaaa 我刚刚意识到这个问题来自近 5 年半前,所以我怀疑有人会看这个答案,呵呵。【参考方案5】:

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

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))

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

【讨论】:

以上是关于如何制作嵌套字典并动态追加数据的主要内容,如果未能解决你的问题,请参考以下文章

Python:展平多个嵌套的字典并追加

如何在 Python 中遍历 N 级嵌套字典?

如何制作一个以字典为输入并输出银行净额的程序?

如何将动态位置数据加载到字典对象/数组中?

python 从列表中取出一个字典元素

如何使用 BeautifulSoup 从 JSON 数据制作 Python 字典