Variablennamen aus Werten anderer Variablen generieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Hallo Forum,

ich möchte die Werte von Variablen in den Variablennamen einer anderen schreiben, diese dann speichern und später wieder darauf zurückzugreifen.
Dafür erzeuge ich zwei Schleifen... die erste erzeugt alle Kombinationen die in der zweiten Schleife gerechnet werden sollen. Die Ergebnisse der zweiten Schleife sollen dann in einer Variablen mit der verwendeten Kombination gespeichert werden.
Als Pythonneuling habe ich es wie bei strings mit format() versucht, funktioniert aber leider nicht. Gibt es da eine weit verbreitete Lösung die ich "noch" nicht kenne ? Hier ein reduziertes (leider nicht lauffähiges) Beispiel meines Codes...

Code: Alles auswählen

import numpy as np
from itertools import product

Nt = 20.
x = np.ones(Nt)

for exp,F in product(np.arange(0,-1.5,-0.5),np.array([0.5e2, 0.6e2, 0.7e2])):
    
    for i in range(int(Nt)):
        x[i] = i + (F * 5 ** exp)
        
    x_exp_{0}_F_{1}.format(exp,F) = x
    
np.savetxt('auto_test.out', ('x_exp_{0}_F_{1}'.format(exp,F))
Danke für eure kreativen Vorschläge !
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Benutzt doch ein dictionary?!?

Code: Alles auswählen

In [1]: x = {}

In [2]: y = 3

In [3]: z = "foo"

In [4]: x[y] = 42

In [5]: x[z] = 21

In [6]: x
Out[6]: {3: 42, 'foo': 21}

In [7]: x[3]
Out[7]: 42
*edit*
Nochmal so am Rande, das was du vorhast würde mit exec() gehen, aber das wäre umständlich und kein guter Stiel.

mfG Lars
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Hey,
an dictionaries habe ich auch gedacht. Probleme gibt es da leider wenn man später den key als Variablennamen verwenden möchte (wie ich :D ) und er einen Punkt enthält. Wie kann man das dann umgehen ?
Ich probiere es mit folgendem Code:

Code: Alles auswählen

for key, value in mydict.items(): 
    exec("%s = %s" % (key, value))
Leider funktioniert das dann eben nicht, falls der value z.B. 400.0 ist !
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Grizzly hat geschrieben:Probleme gibt es da leider wenn man später den key als Variablennamen verwenden möchte (wie ich :D ) und er einen Punkt enthält.
Du möchtest ganz sicher keine Variablennamen generieren, das ist immer (ok, es gibt extrem seltene Ausnahmen) ein Fehler! Wenn du zu so etwas greifen musst, dann machst du etwas falsch und möchtest auf geeigneten Datenstrukturen arbeiten. Typischerweise Listen oder Wörterbücher. Welches Problem versuchst du denn eigentlich zu lösen?
Das Leben ist wie ein Tennisball.
BlackJack

@Grizzly: Kannst Du mal verraten *warum* Du so etwas machen willst? Und ich sehe ehrlich gesagt das Problem nicht. Ausser halt das man von ``exec`` grundsätzlich eher die Finger lassen sollte.
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Ich untersuche die Sensitivität eines Massenflussmodells auf spezielle Kombinationen von Parametern. In meiner Flussformel sind zwei Parameter enthalten die ich variiere um danach alle möglichen Kombinationen daraus zu berechnen.
Um nun nicht den Überblick zu verlieren verwende ich die jeweilige Kombination als key in meinem dictionary.

Auf das erzeugte dictionary greife ich in meinem Plotcode via pickle zu und nun habe ich ein Problem wenn ich den key als variablennamen schreiben möchte um die Werte später zu plotten. Im Sinne von:

Code: Alles auswählen

M_G_exp_0.0_F_50000.0 = mydict2['M_G_exp_0.0_F_50000.0']
wobei M_G der berechnete Fluss und exp bzw. F ein Beispiel einer möglichen Kombination ist...

An dieser Stelle gibt es nun einen Syntax Error...

Habt ihr Verbesserungsvorschläge ? Ich bin für konstruktive Kritik gerne offen...
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Grizzly,

warum sind die Keys von Deinem Dictionary so kompliziert?
Normalerweise beschreiben Variablennamen den Inhalt und nicht die Parameter wie der Inhalt erzeugt wurde:

Code: Alles auswählen

values_to_plot = fluss['M_G',0.0,500000.0]
»mydict2« ist auch kein sinnvoller Variablenname.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die Frage ist je genau, warum du das als Variablenname haben willst. Dass das Syntaktisch nicht möglich ist, hast du ja bereits Festgestellt denn der Punkt-Operator wid als Attributzugriff gewertet. Und auch Keys die Zahlen repräsentieren wirst du nicht als Variable darstellen können. Also wozu?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Grizzly hat geschrieben:Auf das erzeugte dictionary greife ich in meinem Plotcode via pickle zu und nun habe ich ein Problem wenn ich den key als variablennamen schreiben möchte um die Werte später zu plotten. Im Sinne von:

Code: Alles auswählen

M_G_exp_0.0_F_50000.0 = mydict2['M_G_exp_0.0_F_50000.0']
Ich verstehe noch nicht, warum du den Wert im Dictionary unbedingt an einen neuen Bezeichner binden möchtest. Was kannst du damit tun, was du sonst nicht tun kannst?

Mal ein simples Beispiel:

Code: Alles auswählen

data = {'foo': 23, 'bar': 42}
foo = data['foo']
print foo
print data['foo']
Beide Ausgaben ergeben das gleiche. Warum also ergibt sich die Notwendigkeit einer expliziten Zuweisung?
BlackJack

@Grizzly: Ich möchte auch noch mal gerne wissen *warum*? Wenn man einen Variablennamen erzeugt, den man niemals irgendwo selber per Hand eingibt, dann braucht man den doch nicht erzeugen. Denn wenn immer nur „programmatisch” darauf zugegriffen wird, kann man auch ganz einfach auf das sowieso schon existierende Wörterbuch zugreifen. Und da können die Schlüssel auch gerne mal Punkte enthalten, oder sonst etwas was in Python syntaktisch für Namen nicht möglich ist.

Edit: Wobei ich das im Schlüssel auch nicht unbedingt zu einer Zeichenkette verschmelzen würde. Man kann ja auch Tupel mit den Teilwerten als Schlüssel verwenden.
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Danke für eure schnellen Antworten.

Das ich den Wert direkt weiterverwenden kann habe ich auch gerade gemerkt, daher ist die Zuweisung unnütz.

@Sirius3: Ich möchte also an späterer Stelle auf die Parameter mit denen der Inhalt erzeugt wurde zurückgreifen um z.B. die Flüsse in Abhängigkeit von den verwendeten Parametern zu plotten. Dafür wollte ich die Parameter in den Variablennamen schreiben und das ist wohl ein Fehler.
Ich müsste also die Parameter an mein dictionary automatisch "anhängen", da ich etwa 50 Kombinationen habe...

Um also z.B. den key 'M_G' mit dem "Anhang" 0.0,50000.0 zu erhalten müsste ich bei der Dictionaryerstellung schon feilen.

Im Sinne von:

Code: Alles auswählen

import numpy as np
import pickle
from itertools import product

for exp,F in product(np.arange(0,-2.5,-0.5),np.array([0.5e5, 0.6e5, 0.7e5, 0.8e5, 0.9e5, 1.0e5, 1.1e5, 1.2e5, 1.3e5, 1.4e5])):
     M_G = ... # berechne M_G mit allen Kombinationen aus exp und F

fluss['M_G',{0},{1}.format(exp,F)] = M_G
output = open('my_file.pkl', 'wb')
pickle.dump(fluss, output)
output.close()

Oder wie würde man das dann Umsetzen ?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Oben wurde der Tipp doch schon gegeben: Erstelle keine Schlüssel als String, sondern verwende die Werte direkt als Tupel. Dann kannst du auch wieder problemlos auf diese zugreifen:

Code: Alles auswählen

fluss[exp, F] = M_G
Das Leben ist wie ein Tennisball.
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Aha Erlebnis !

Vielen Dank für eure Mühen, jetzt habe ich ein fluss-dictionary mit den Werten als keys und den Flüssen als values.
Ich hoffe das Ganze jetzt noch zu plotten wird nicht mehr so aufwendig für mich.
Benutzeravatar
Grizzly
User
Beiträge: 34
Registriert: Sonntag 10. Februar 2013, 21:18

Verzeiht mir die Anfängerfrage, aber das plotten ist doch sehr aufwendig für mich...

Ich möchte den ersten key als x-Werte, den zweiten als y-Werte und den dazugehörigen value als z-Wert plotten (soll punktwolke werden)

Bisher erreiche ich die keys jedoch nur gepaart mit fluss.keys() und schaffe es nicht sie in 2 arrays zu schreiben. Ein dritter array sollte nun aus dem dazugehörigen value entstehen um das ganze dann mit matplotlib als punktewolke zu plotten... Könnt ihr mir nochmals unter die Arme greifen ?
BlackJack

Ungetestet:

Code: Alles auswählen

    xs, ys, zs = list(), list(), list()
    for (x, y), z in fluss.iteritems():
        xs.append(x)
        ys.append(y)
        zs.append(z)
Antworten