In einer vorgegebenen Liste von Variablennamen in Python, wie kann ich ein Wörterbuch mit den Variablennamen als Schlüssel erstellen (auf die Variablen Werte)?

StackOverflow https://stackoverflow.com/questions/230896

  •  04-07-2019
  •  | 
  •  

Frage

Ich habe eine Liste von Variablennamen, wie folgt aus:

['foo', 'bar', 'baz']

(Ich fragte ursprünglich, wie ich eine Liste von Variablen zu konvertieren. Siehe Greg Hewgill Antwort unten).

Wie kann ich wandeln diese in ein Wörterbuch, wo die Schlüssel die Variablennamen (als Strings) sind und die Werte sind die Werte der Variablen?

{'foo': foo, 'bar': bar, 'baz': baz}

Jetzt, wo ich wieder die Frage zu stellen, kam ich mit:

d = {}
for name in list_of_variable_names:
    d[name] = eval(name)

Kann das verbessert werden?

Aktualisieren , auf die Frage reagiert (in einem Kommentar), warum ich wollen würde, dies zu tun:

Ich finde ich oft das% Operator mit einem Wörterbuch von Namen und Werten in Strings interpolieren. Oft sind die Namen in der Zeichenfolge nur die Namen der lokalen Variablen. So (mit der Antwort unten) kann ich so etwas tun:

message = '''Name: %(name)s
ZIP: %(zip)s

Dear %(name)s,
...''' % dict((x, locals()[x]) for x in ['name', 'zip'])
War es hilfreich?

Lösung

Vergessen Filterung locals()! Das Wörterbuch, das Sie die Formatierung Zeichenfolge geben darf nicht verwendete Schlüssel enthalten:

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> locals()
{'name': 'foo', 'zip': 123, ... 'unused': 'whoops!', ...}
>>> '%(name)s %(zip)i' % locals()
'foo 123'

Mit dem neuen f-string-Funktion in Python 3.6 unter Verwendung von locals() ist nicht mehr notwendig:

>>> name = 'foo'
>>> zip = 123
>>> unused = 'whoops!'
>>> f'{zip: >5} {name.upper()}'
'  123 FOO'

Andere Tipps

Ihre ursprüngliche Liste [foo, bar, baz] nicht die Variable enthält Namen , es enthält nur Elemente, die Werte zu den gleichen siehe als die Variablen, die Sie aufgelistet. Dies liegt daran, dass Sie zwei unterschiedliche Variablennamen haben können, die auf den gleichen Wert beziehen.

die Liste von selbst Also, enthält keine Informationen über das, was andere Namen auf die Objekte beziehen. Das erste Element im Array hat den Namen foo aber es hat auch den Namen a[0] (vorausgesetzt, Ihr Array wird a genannt). Nach dem folgenden Code ausführt, quux bezieht sich auch auf das gleiche Objekt:

quux = a[0]

Update: Sie haben Recht, dass Sie eval() dafür verwenden können, aber seine Verwendung wird im Allgemeinen abgeraten. Python stellt ein spezielles Element namens __dict__ , die die Symboltabelle enthält für das aktuelle Modul. So können Sie:

import __main__
d = dict((x, __main__.__dict__[x]) for x in list_of_variable_names)

Mit auf import __main__, wenn Ihr Code in dem unbenannte Hauptmodul ist eine Marotte von Python.

Sie können die Liste oder Generator Comprehensions verwenden, um eine Liste von Schlüsseln, Wertetupeln bauen verwendet, um direkt einen dict zu instanziiert. Der beste Weg ist unter:

dict((name, eval(name)) for name in list_of_variable_names)

Darüber hinaus, wenn Sie wissen zum Beispiel, dass die Variablen in der lokalen Symboltabelle existieren Sie sich von der gefährlichen eval sparen können, indem Sie die Variable direkt von Einheimischen:

dict((name, locals()[name]) for name in list_of_variable_names)

Nach Ihrer letzten Aktualisierung, ich denke, die Antwort unten wirklich ist, was Sie wollen. Wenn Sie nur diese mit Saiten für Streich Erweiterung, die Sie steuern, nur Einheimischen () übergeben direkt an die Saite Expansion und es werden die gewünschten Werte kirsch auswählen

Wenn jedoch könnten diese Saiten jemals kommen aus einer externen Quelle (z Übersetzungsdateien), als es ist eine gute Idee, den Einheimischen zu filtern ()

Nicht effizient, aber ohne Aufruf eval:

dict((k,v) for (k,v) in globals().iteritems() if k in list_of_variable_names)

oder

dict((k,v) for (k,v) in vars().iteritems() if k in list_of_variable_names)

je nachdem, was Sie wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top