2010-09-04 15 views
7

Lo que trato de hacer es obtener 3 valores de una clave en variables separadas. Actualmente lo estoy haciendo de esta manera:Múltiples valores para la clave en el diccionario en Python

for key in names: 
    posX = names[key][0] 
    posY = names[key][1] 
    posZ = names[key][2] 

Esto no parece muy intuitivo para mí a pesar de que funciona. También he intentado hacer esto:

for key, value in names: 
    location = value 

Desafortunadamente, esto me da un solo objeto (que es lo que esperaba), pero necesito los valores individuales asignados a la tecla. Gracias y me disculpo por mi novedad en Python.

Actualización Disculpa por no especificar de dónde obtenía mis valores. Así es como lo estoy haciendo para el primer ejemplo.

names = {} 

for name in objectNames: 
    cmds.select(name) 
    location = cmds.xform(q=True, ws=True, t=True) 
    names[name] = location 
+0

Esto era lo que mi último intento llegó a ser: nombres = {} de nombre en objectnames: \t cmds.seleccione (nombre) \t ubicación = cmds.xform (q = True, ws = True, t = True) \t nombres [nombre] = ubicación para la llave, (posX, ramillete, posZ) en names.items() : \t jointPosX = posX \t jointPosY = posY \t jointPosZ = posZ –

Respuesta

11

No es nada intuitivo.

La única forma de almacenar "valores múltiples" para una clave determinada en un diccionario es almacenar algún tipo de objeto contenedor como el valor, como una lista o tupla. Puede acceder a una lista o tupla subindicando, como lo hace en su primer ejemplo.

El único problema con su ejemplo es que es la manera fea e inconveniente de acceder a dicho contenedor cuando se usa de esta manera. Inténtelo de este tipo, y probablemente será mucho más feliz:

>>> alist = [1, 2, 3] 
>>> one, two, three = alist 
>>> one 
1 
>>> two 
2 
>>> three 
3 
>>> 

Así, su segundo ejemplo podría ser en su lugar:

for key, value in names.items(): 
    posX, posY, posZ = value 

Como señala FabienAndre en un comentario más abajo, hay también la más conveniente sintaxis que había olvidado por completo, for key,(posX,posY,posZ) in names.items():.

No especifica de dónde obtiene estos valores, pero si provienen de código que tiene control, y puede depender del uso de Python 2.6 o posterior, también puede consultar named tuples. Posteriormente, se podría proporcionar una tupla nombrado como el valor dict, y el uso de la sintaxis pos.x, pos.y, etc., para acceder a los valores:

for name, pos in names.items(): 
    doSomethingWith(pos.x) 
    doSomethingElseWith(pos.x, pos.y, pos.z) 
+2

También mencionaría 'for key, (posX, posY, posZ) en names.items():' – FabienAndre

+0

Intenté usar su método, pero seguí obteniendo Error: demasiados valores para descomprimir. Sin embargo, cuando utilicé su segundo ejemplo de FabienAndre, funcionó perfectamente. Creo que el primer ejemplo no funcionó debido a cómo estoy obteniendo mis datos en Maya, pero podría estar completamente equivocado. ¡Gracias a los dos! –

+0

@Arrant: Probablemente captó mi primer método antes de agregarle .items(). Siempre me olvido de que por más o menos la misma razón por la que siempre me olvido de la sintaxis de Fabien, mi cerebro tiende a olvidar cosas "implícitas". :) –

2

Si no te importa una dependencia externa, podría incluir Werkzeug's MultiDict:

A MultiDict is a dictionary subclass customized to deal with multiple values for the same key which is for example used by the parsing functions in the wrappers.

>>> d = MultiDict([('a', 'b'), ('a', 'c')]) 
>>> d 
MultiDict([('a', 'b'), ('a', 'c')]) 
>>> d['a'] 
'b' 
>>> d.getlist('a') 
['b', 'c'] 
>>> 'a' in d 
True 

Otra manera de almacenar varios valores para una clave es usar un tipo de contenedor, como una list, set o tuple.

+0

no me importa dependencias externas en absoluto, así que voy a dar a este un giro para ver si es más rápido o no. –

2

a mirar tu código, trabajando con variables de posición/ubicación, también se puede unificar la X, y y Z posición en un tipo común, por ejemplo utilizando tuplas designada:

from collections import namedtuple 

Position = namedtuple("Position", "x, y, z") 

locations = { 
    "chair": Position(1, 2, 5.3), 
    "table": Position(5, 3.732, 6), 
    "lamp": Position(4.4, 7.2, 2) 
} 

print "Chair X location: ", locations["chair"].x 

Sólo una sugerencia, sin embargo.

+0

No había pensado en hacer algo como esto, pero puedo usarlo en otras partes de mi código actual, ya que esta parece una muy buena manera de dividir las cosas, sin dejar de tener sentido. –

+0

¿Cómo rellenar las ubicaciones de los objetos de forma dinámica? – Punit

Cuestiones relacionadas