2012-03-21 16 views
5

Estoy tratando de encontrar una manera de eliminar los sombreadores duplicados en Maya usando Python Dictionaries.Extraer valores duplicados de un diccionario

Esto es lo que estoy haciendo:

quiero poner todos los shaders maya en un diccionario como llaves y poner el archivo de textura como el valor correspondiente. Luego quiero que la secuencia de comandos se ejecute en el diccionario y encuentre las claves que comparten el mismo valor y las rellene en una matriz u otro diccionario.

Esto es básicamente lo que tengo en este momento:

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

duplicate_shaders_dict = {}` 

cómo puede ahora ejecutar a través de ese diccionario para compilar otro diccionario que se ve algo como esto:

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

Y la parte difícil estar dado que hay duplicados, quiero que el script sea skip the original key, por lo que no se rellena para duplicar el diccionario de shaders.

+3

Supongo que por "la clave original" quiere decir 'a' en su ejemplo. Me gustaría señalar que los diccionarios no están ordenados, y que "la clave original" solo puede significar "el primero encontrado". – freespace

Respuesta

3

Una solución simple es invertir el diccionario. Teniendo en cuenta:

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

se puede invertir de esta manera:

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

que le ofrece:

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

Y si revertir eso, usted tiene el diccionario original con duplicados retira:

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

y donde esta el dict con los valores duplicados? – juliomalegria

+0

Huh, se perdió esa parte. Esto comienza con la parte "lo que tengo" de la pregunta y arroja la parte "lo que quiero", por lo que probablemente sea un buen lugar para comenzar. – larsks

+0

Esto tiene sentido: pero no quiero deshacerme de los duplicados, necesito ponerlos en otra variable para que luego pueda actuar sobre ellos y luego eliminarlos de la escena –

4

I would pr Obably hacer algo como esto. En primer lugar, hacer que el diccionario inverso:

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

Esto básicamente invierte el diccionario haciendo un bucle sobre cada llave, pareja de valores y añadiendo la clave para una lista asociada con el valor.

luego dividir esto:

>>> 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. Esto supone que los archivos de textura son manejables y que pueden servir como claves del diccionario. Si no lo son, entonces tendría que trabajar en eso. Además, dado que como notas de @freespace no hay orden aquí, si quería un orden en particular, tendríamos que iterar sobre claves ordenadas o similares.

-

Actualización: No me gusta mucho la anterior. Versión más corta basada en 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

¡Este lo hizo! aunque es un poco "mágico" para mí. Voy a estudiar esta solución. –

+0

+1 para la actualización ... –

Cuestiones relacionadas