2010-09-04 8 views
7

Ce que j'essaie de faire est d'obtenir 3 valeurs d'une clé dans des variables séparées. Actuellement, je le fais comme ceci:Plusieurs valeurs pour la clé dans le dictionnaire en Python

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

Cela ne me semble pas très intuitif, même si cela fonctionne. J'ai aussi essayé de faire ceci:

for key, value in names: 
    location = value 

Malheureusement, cela me donne un seul objet (qui est ce que je m'y attendais), mais je dois les valeurs individuelles affectées à la clé. Merci et excusez pour ma nouveauté à Python.

Mise à jour Toutes mes excuses pour ne pas préciser d'où je tirais mes valeurs. Voici comment je le fais pour le premier exemple.

names = {} 

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

Ce fut ce que ma dernière tentative est sorti comme: nom = {} pour nom objectnames: \t cmds.sélectionnez (nom) \t location = cmds.xform (q = True, ws = True, t = True) \t noms [name] = emplacement pour la clé, (posX, posY, POSZ) dans names.items() : \t jointPosX = posX \t jointPosY = posY \t jointPosZ = POSZ –

Répondre

11

Ce n'est pas illogique du tout. La seule façon de stocker des «valeurs multiples» pour une clé donnée dans un dictionnaire consiste à stocker une sorte d'objet conteneur comme valeur, telle qu'une liste ou un n-uplet. Vous pouvez accéder à une liste ou à un tuple en l'inscrivant, comme vous le faites dans votre premier exemple.

Le seul problème avec votre exemple est que c'est la manière la plus laide et la plus pratique d'accéder à un tel conteneur quand il est utilisé de cette façon. Essayez comme ça, et vous serez probablement beaucoup plus heureux:

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

Ainsi votre deuxième exemple pourrait plutôt être:

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

Comme le souligne FabienAndre dans un commentaire ci-dessous, il y a aussi plus pratique syntaxe que j'avais complètement oublié, for key,(posX,posY,posZ) in names.items():. Vous ne spécifiez pas d'où vous obtenez ces valeurs, mais si elles proviennent du code que vous contrôlez et que vous pouvez compter sur Python 2.6 ou ultérieur, vous pouvez également regarder dans named tuples. Ensuite, vous pouvez fournir un tuple nommé la valeur dict et utilisez la syntaxe pos.x, pos.y, etc. pour accéder aux valeurs:

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

Je voudrais également mentionner 'pour la clé, (posX, posY, posZ) dans names.items():' – FabienAndre

+0

J'ai essayé d'utiliser votre méthode, mais a continué à obtenir Erreur: trop de valeurs à décompresser. Cependant, lorsque j'ai utilisé votre deuxième exemple de FabienAndre, cela a fonctionné parfaitement. Je pense que le premier exemple n'a pas fonctionné à cause de la façon dont je reçois mes données dans Maya, mais je peux me tromper complètement. Merci à vous deux! –

+0

@Arrant: Vous avez probablement détecté ma première méthode avant d'y ajouter .items(). J'oublie toujours que pour à peu près la même raison j'oublie toujours la syntaxe de Fabien, mon cerveau a tendance à oublier les choses «implicites». :) –

2

Si cela ne vous dérange pas une dépendance externe, vous pouvez inclure 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 

Une autre façon de stocker plusieurs valeurs pour une clé est d'utiliser un type de conteneur, comme un list, un set ou un tuple.

+0

cela ne me dérange pas les dépendances externes du tout, donc je vais donner ce un tourbillon pour voir si elle est plus rapide ou non. –

2

En regardant votre code, travailler avec des variables de position/emplacement, vous pouvez aussi unifier X, Y et Z position dans un type commun, par exemple en utilisant nommé tuples:

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 

Juste une suggestion, cependant.

+0

Je n'avais pas pensé à faire quelque chose comme ça, mais je peux l'utiliser dans d'autres parties de mon code actuel, car cela semble un très bon moyen de diviser les choses, tout en ayant du sens. –

+0

Comment remplir dynamiquement les emplacements des objets? – Punit

Questions connexes