Étant donné une liste de noms de variables en Python, comment puis-je créer un dictionnaire avec les noms de variables comme les touches (pour les valeurs des variables)?
J'ai une liste de noms de variable, comme ceci:
['foo', 'bar', 'baz']
(Je l'ai d'abord demandé comment je la conversion d'une liste de variables. Voir Greg Hewgill la réponse ci-dessous.)
Comment puis-je convertir ce pour un dictionnaire dont les clés sont les noms des variables (comme des chaînes de caractères) et les valeurs sont les valeurs des variables?
{'foo': foo, 'bar': bar, 'baz': baz}
Maintenant que je suis re-poser la question, je suis venu avec:
d = {}
for name in list_of_variable_names:
d[name] = eval(name)
Cela peut-il être amélioré?
Mise à jour, de répondre à la question (dans un commentaire) pourquoi je veux le faire:
Je me retrouve souvent à l'aide de l'opérateur % pour les chaînes avec un dictionnaire de noms et de valeurs à interpoler. Souvent le nom de la chaîne est juste les noms de variables locales. (Avec la réponse ci-dessous), je peux faire quelque chose comme ceci:
message = '''Name: %(name)s
ZIP: %(zip)s
Dear %(name)s,
...''' % dict((x, locals()[x]) for x in ['name', 'zip'])
Réponse à la mise à jour en réponse à mon commentaire: Le langage Python pour le faire (que je ne supporte pas, mais je l'ai vu utilisé), est "string % des habitants (en)" directement.
Vous pouvez remplacer
dict((x, locals()[...)
par juste vars()
.Exemple:
a, b = 1, 'astring'; print("%(a)s %(b)s %(b)r" % vars())
OriginalL'auteur Daryl Spitzer | 2008-10-23
Vous devez vous connecter pour publier un commentaire.
Oublier de filtrage
locals()
! Le dictionnaire que vous donnez à la chaîne de formatage est autorisé à contenir les touches non utilisées:Avec la nouvelle f-chaîne de caractéristique en Python 3.6, à l'aide de
locals()
n'est plus nécessaire:'{name} {zip}'.format(**locals())
OriginalL'auteur
Votre liste d'origine
[foo, bar, baz]
ne contient pas la variable noms, il contient uniquement les éléments qui se réfèrent à la même valeurs que les variables que vous avez énumérés. C'est parce que vous pouvez avoir deux noms de variables qui font référence à la même valeur.Donc, la liste en elle même ne contient pas d'informations sur les autres noms se réfèrent à des objets. Le premier élément dans votre tableau avec le nom de
foo
mais il a aussi le nom dea[0]
(en supposant que votre tableau est appeléa
). Après l'exécution du code suivant,quux
fait également référence au même objet:Mise à jour: Vous avez raison, vous pouvez utiliser
eval()
pour cela, mais son utilisation est généralement déconseillée. Python offre un membre nommé__dict__
qui contient la table des symboles pour le module en cours. Ainsi, vous pouvez:Avoir à
import __main__
lorsque votre code est dans le sans nom module principal est un caprice de Python.OriginalL'auteur Greg Hewgill
Vous pouvez utiliser la liste de générateur ou de compréhensions à construire une liste de clé, valeur tuples utilisé pour instancier directement un dict. La meilleure façon est ci-dessous:
En outre, si vous savez, par exemple, que les variables existent dans le local la table des symboles, vous pouvez vous enregistrer à partir de la dangereuse eval en regardant la variable directement à partir d'habitants:
Après votre dernière mise à jour, je pense que la réponse ci-dessous est vraiment ce que vous voulez. Si vous êtes juste en utilisant cette chaîne d'extension avec des chaînes qui vous contrôle, il suffit de passer les habitants() directement à la chaîne de l'expansion et il va piocher dans les valeurs souhaitées
Si, toutefois, ces chaînes ne pourrait jamais venir à partir d'une source externe (par exemple des fichiers de traduction), que c'est une bonne idée pour filtrer les habitants()
D'accord, "..." % locals() est beaucoup plus Pythonic trop, que c'est un idiome commun.
J'ai obtenu ce travail en utilisant des dict([(nom, locals()[nom]) pour le nom dans list_of_variable_names])
OriginalL'auteur Douglas Mayle
Pas efficace, mais sans invoquer
eval
:ou
selon ce que vous voulez.
OriginalL'auteur ephemient