2012-03-21 15 views
5

Sto cercando di trovare un modo per eliminare gli ombreggiatori duplicati in Maya usando i dizionari Python.Estrarre valori duplicati da un dizionario

Ecco quello che sto facendo:

voglio mettere tutte le shader maya in un dizionario come chiavi e mettere il file di texture corrispondente come valore. Quindi voglio che lo script esegua il dizionario e trovi le chiavi che condividono lo stesso valore e le inseriscono in un array o in un altro dizionario.

Questo è fondamentalmente ciò che ho in questo momento:

shaders_dict = {'a': somePath, 'b': somePath, 
       'c': differentPath, 'd': differentPath} 

duplicate_shaders_dict = {}` 

come posso ora gestito attraverso quel dizionario di compilare un dizionario che sembra qualcosa di simile:

duplicate_shaders_dict = {'b':somePath, 'd':differentPath } 

E la parte difficile essere dal momento che ci sono duplicati, voglio che lo script sia skip the original key in modo che non venga inserito nel dizionario degli ombreggiatori duplicati.

+3

Suppongo che "la chiave originale" indichi "a" nell'esempio. Vorrei sottolineare che i dizionari non sono ordinati e "la chiave originale" può significare solo "il primo incontrato". – freespace

risposta

3

Una soluzione semplice è quella di invertire il dizionario. Dato:

>>> d = {'a': 'somePath', 'b': 'somePath', 
... 'c': 'differentPath', 'd': 'differentPath'} 

si può invertire in questo modo:

>>> r = dict((v,k) for k,v in d.iteritems()) 

che ti dà:

>>> r 
{'differentPath': 'd', 'somePath': 'b'} 

E se si invertire tale, si ha la dizionario originale con i duplicati rimossi:

>>> d = dict((v,k) for k,v in r.iteritems()) 
>>> d 
{'b': 'somePath', 'd': 'differentPath'} 
+0

e dov'è il dict con i valori duplicati? – juliomalegria

+0

Huh, ho perso quella parte. Questo inizia con la parte "che ho" della domanda e produce la parte "ciò che voglio", quindi probabilmente è un buon punto di partenza. – larsks

+0

Questo ha senso: ma non voglio semplicemente sbarazzarmi dei duplicati, ho bisogno di metterli in un'altra variabile in modo che in seguito io possa agire su di loro e poi cancellarli dalla scena –

4

Vorrei pr fare diversamente qualcosa di simile. In primo luogo, rendere il dizionario inversa:

>>> from collections import defaultdict 
>>> 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> 
>>> inverse_dict = defaultdict(list) 
>>> for k,v in shaders_dict.iteritems(): 
...  inverse_dict[v].append(k) 
... 
>>> inverse_dict 
defaultdict(<type 'list'>, {'differentPath': ['c', 'd'], 'somePath': ['a', 'b']}) 

Questo inverte fondamentalmente il dizionario da loop su ogni tasto, coppia di valori e aggiungendo la chiave per una lista associata al valore.

Poi dividere questo:

>>> first_shaders_dict = {} 
>>> duplicate_shaders_dict = {} 
>>> for v, ks in inverse_dict.iteritems(): 
...  first, rest = ks[0], ks[1:] 
...  first_shaders_dict[first] = v 
...  for r in rest: 
...   duplicate_shaders_dict[r] = v 
... 
>>> first_shaders_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_shaders_dict 
{'b': 'somePath', 'd': 'differentPath'} 

Hmm. Ciò presuppone che i file delle texture siano lavabili e quindi possano fungere da chiavi del dizionario. Se non lo sono, allora dovrei risolvere il problema. Inoltre, dato che @freespace dice che non c'è ordine qui, se volessi un particolare ordine dovremmo iterare su chiavi ordinate o simili.

-

Update: Non mi è piaciuta la di cui sopra molto. Versione più breve basata su itertools:

>>> import itertools 
>>> shaders_dict = {'a':'somePath', 'b':'somePath', 'c':'differentPath', 'd':'differentPath'} 
>>> keys = sorted(sorted(shaders_dict),key=shaders_dict.get) 
>>> by_val = [(v, list(ks)) for v, ks in itertools.groupby(keys, shaders_dict.get)] 
>>> first_dict = dict((ks[0],v) for v,ks in by_val) 
>>> duplicate_dict = dict((k,v) for v,ks in by_val for k in ks[1:]) 
>>> first_dict 
{'a': 'somePath', 'c': 'differentPath'} 
>>> duplicate_dict 
{'b': 'somePath', 'd': 'differentPath'} 
+0

Questo lo ha fatto! anche se è una specie di "magia" per me. Ho intenzione di studiare questa soluzione. –

+0

+1 per l'aggiornamento ... –

Problemi correlati