python返回字典

时间:2015-09-07 11:34:32

标签: python dictionary maya

我正在寻找这个问题的几个小时和几个小时,并尝试了一切可能,但我不能破解它,我很安静的字典菜鸟。

我与maya一起工作并且得到了灯光的冲突名称,当你复制一个组时会发生这种情况,所有的孩子都被命名为和以前一样,所以在一个组中有一个ALL_KEY会在另一个组中产生一个带有key_char的冲突名称。 / p>

我需要识别短名称的冲突名称并返回长名称,以便我可以执行打印长名称为double或甚至cmds.select。 不幸的是,我在互联网上找到的所有内容都是关于如果一个列表包含双重值而返回,只返回True或False,这对我来说没用,所以我尝试了列表清理和列表比较,但是我遇到了一个字典同时保持长短名称。 我设法获取短名称,如果它们是重复的并返回它们,但是在长途名称丢失的路上,所以我当然不能再清楚它了。

>import itertools 
>import fnmatch 
>import maya.cmds as mc 
>LIGHT_TYPES = ["spotLight", "areaLight", "directionalLight", "pointLight", "aiAreaLight", "aiPhotometricLight", "aiSkyDomeLight"]


#create dict
dblList = {'long' : 'short'}
for x in mc.ls (type=LIGHT_TYPES, transforms=True):
    y = x.split('|')[-1:][0]
    dblList['long','short'] = dblList.setdefault(x, y)



#reverse values with keys for easier detection
rev_multidict = {}
for key, value in dblList.items():
    rev_multidict.setdefault(value, set()).add(key)

#detect the doubles in the dict
#print [values for key, values in rev_multidict.items() if len(values) > 1]
flattenList = set(itertools.chain.from_iterable(values for key, values in rev_multidict.items() if len(values) > 1))

#so by now I got all the long names which clash in the scene already!
#means now I just need to make a for loop strip away the pipes and ask if the object is already in the list, then return the path with the pipe, and ask if the object is in lightlist and return the longname if so.
#but after many many hours I can't get this part working.
##as example until now print flattenList returns
>set([u'ALL_blockers|ALL_KEY', u'ABCD_0140|scSet', u'SARAH_TOPShape', u'ABCD_0140|scChars', u'ALL|ALL_KEY', u'|scChars', u'|scSet', u'|scFX', ('long', 'short'), u'ABCD_0140|scFX'])

#we see ALL_KEY is double! and that's exactly what I need returned as long name

#THIS IS THE PART THAT I CAN'T GET WORKING, CHECK IN THE LIST WHICH VALUES ARE DOUBLE IN THE LONGNAME AND RETURN THE SHORTNAME LIST.
THE WHOLE DICTIONARY IS STILL COMPLETE AS 
seen = set()
uniq = []
for x in dblList2:
    if x[0].split('|')[-1:][0] not in seen:
        uniq.append(x.split('|')[-1:][0])
        seen.add(x.split('|')[-1:][0])

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我要用这个刺。如果这不是你想要的,请告诉我原因。

如果我有一个像这样的层次结构的场景:

group1
  nurbsCircle1
group2
  nurbsCircle2
group3
  nurbsCircle1

我可以运行它(如果您需要选择或等等,请调整ls()):

conflictObjs = {}
objs = cmds.ls(shortNames = True, transforms = True)
for obj in objs:
    if len( obj.split('|') ) > 1:
        conflictObjs[obj] = obj.split('|')[-1]

conflictObjs的输出将是:

# Dictionary of objects with non-unique short names
# {<long name>:<short name>}
{u'group1|nurbsCircle1': u'nurbsCircle1', u'group3|nurbsCircle1': u'nurbsCircle1'}

向我显示哪些对象没有唯一的短名称。

答案 1 :(得分:0)

这将为您提供所有具有重复短名称的灯的列表,按重复名称分组,并包括重复对象的完整路径:

def clashes_by_type(*types):
    long_names = cmds.ls(type = types, l=True) or []
    # get the parents from the lights, not using ls -type transform
    long_names = set(cmds.listRelatives(*long_names, p=True, f=True) or [])
    short_names = set([i.rpartition("|")[-1] for i in long_names])
    short_dict = dict()
    for sn in short_names:
        short_dict[sn] = [i for i in long_names if i.endswith("|"+ sn)]
    clashes = dict((k,v) for k, v in short_dict.items() if len(v) > 1)
    return clashes

clashes_by_type('directionalLight', 'ambientLight')The main points to note:
  1. 从长名称开始工作。短名称本身就不可靠!
  2. 在派生短名称时,包括最后一个管道,这样就不会出现常见名称的意外重叠
  3. short_names将始终是列表列表,因为它是由理解创建的
  4. 一旦你有了一个(名字,[带有那个短名字的对象]的词典),通过寻找超过1的值就很容易发生冲突