2015-09-07 1 views
-2

Я ищу часы и часы по этой проблеме и пробовал все возможное, но я не могу разобраться, я тихонький словарь noob.python return double entry в словаре

Я работаю с майей и сталкиваюсь с именами огней, это происходит, когда вы дублируете группу, все дети называются такими же, как и раньше, поэтому наличие ALL_KEY в одной группе приводит к конфликтующему имени с key_char в другой группе.

Мне нужно идентифицировать связующее имя короткого имени и вернуть длинное имя, чтобы я мог напечатать длинное имя, это двойное или даже 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]) 

благодарит за вашу помощь.

+0

Я просто хочу отметить, что это: 'dblList ['long', 'short'] = dblList. setdefault (x, y) 'willl приведет к dict, который выглядит так:' {'long': 'short', ('long', 'short'): y, x: y} '. Это то, что вы хотели? – IanAuld

+0

нет, но я не знаю, как еще заполнить словарь, это мой первый раз. –

+1

Пожалуйста, отредактируйте свой вопрос с помощью желаемого результата. Трудно будет вам помочь, если я не уверен, чего вы пытаетесь достичь. Тем временем, пожалуйста, прочитайте подробнее о том, как работают словари [здесь] (https://docs.python.org/2/tutorial/datastructures.html#dictionaries). – IanAuld

ответ

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'} 

Показаны мне, что объекты не имеют уникальный ш ort имена.

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. когда у вас есть Dict из (name, [objects with this shortname]) легко получить столкновения, ища значения дольше, чем 1