Problem mit verschachtelten Tupels in Listen in Dictionarys

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
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Moin Moin,

mein Hirnschmalz hat grade versagt, deswegen stelle ich hier mal die Frage.

Situation:
Ich habe ein Dict mit einer Reihe an Parametern:

Code: Alles auswählen

parameter_list = {
    "para1" : "",
    "para2" : "",
    "para3" : "",
    "para4": "",
 ...
}
die Parameter sind zu Anfang alle leer.
Dann habe ich eine Liste mit Konfigurationen:

Code: Alles auswählen

config_list = [
    {
        "name" : "bla",
        "file" : "hier\und\da1.csv",
        ...
        "params" : [
            (parameter_list["para1"], 5),
            (parameter_list["para4"], 47),
            ...
            ]
     }
     ...
]
Die Logik dahinter ist, das ich eine Reihe von Parametern habe, und dann eine Reihe an csv-Dateien einlese, und dann jeweils bestimmte Parameter mit einem Wert aus einer bestimmten Spalte in der csv-Datei fülle.
So weit so klar?

Mein Problem ist jetzt das zuweisen der Werte.
Ich habe eine Funktion, die bekommt eine Konfiguration und das Parameter-Diktionary übergeben, und soll dann die entsprechende csv-Datei laden und die Werte zuweisen.

Code: Alles auswählen

reader = csv.reader(...)
for row in reader:
    if <bedingungen an die Reihe sind erfüllt>
        for par in params:
            par[0] = row[par[1]]
Meinem Verständnis nach müsste par[0] hier ein Verweis auf einen Parameter in parameter_list sein, und row[par[1]] müsste die entsprechende, in der config_list angegebene Spalte in der csv-Datei sein.
Leider bekomme ich so die Fehlermeldung

Code: Alles auswählen

par[0] = row[par[1]]
TypeError: 'tuple' object does not support item assignment
Lasse ich mit "par" in der for-Schleife ausgeben, kommt da z.B. (' ', 5), was ja richtig wäre, also müssten ja par[0] und par[1] die entsprechenden Werte sein. Und auch sie werden richtig ausgeben.
Warum kann ich da dann keine Zuweisung machen, und wieso steht in der Fehlermeldung was von 'tupel'? Auf das Tupel (als solches) greife ich an der Stelle ja gar nicht zu.

Kann mir da jemand helfen das hin zu bekommen?
Oder gibt es vielleicht einen viel leichteren (übersichtlicheren) Ansatz, um das zu lösen?

Danke!
r.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Nachtrag:
an anderer Stelle ist der Parameter kein String, sondern eine Liste, und da klappt es:

Code: Alles auswählen

for par in params:
            par[0].extend(temp)
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Tupel sind im Gegensatz zu Listen 'immutable'.
Bei 'params' willst Du die Werte in den Tupeln direkt
verändern, daher solltet Du statt einer Liste von
Tupeln eine Liste von Listen nehmen.

Kleines Beispiel:

Code: Alles auswählen


In [1]: t = (1,2)

In [2]: t[0] = 3
---------------------------------------------------------------------------
<type 'exceptions.TypeError'>             Traceback (most recent call last)

/home/dirk/<ipython console> in <module>()

<type 'exceptions.TypeError'>: 'tuple' object does not support item assignment

In [3]: t = ([1,2],3)

In [4]: t[0][0] = 4

In [5]: t
Out[5]: ([4, 2], 3)

:wink:
yipyip
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Danke für deine Antwort, aber leider läuft das auch noch nicht ganz rund. Wenn ich keine Tupel sondern Listen verwende, kommt zwar keine Fehlermeldung, aber die Werte werden auch nicht übernommen.

Code: Alles auswählen

parameter_list = {
    "para1" : "",
    "para2" : "",
    "para3" : "",
    "para4": "",
 ...
}

...

config_list = [
    {
        "name" : "bla",
        "file" : "hier\und\da1.csv",
        ...
        "params" : [
            [parameter_list["para1"], 5],
            [parameter_list["para4"], 47],
            ...
            ]
     }
     ...
]

...

for par in paras:
                    par[0] = row[par[1]]
die Parameter bleiben einfach leer.

Als workarount hatte ich einfach die Parameter selber nicht als Strings sondern als Listen angelegt, und dann per append anstelle von "=" jeweils nur einen Wert in die Liste eingefügt.
An der Stelle wo ich sie brauche kann man sie dann ja einfach mittels

Code: Alles auswählen

if type(wert) is list:
        id = id[0]
in einen String umwandeln.

Ist zwar nicht schön, funktioniert aber wenigstens.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Ungetestet:

Code: Alles auswählen

...
config_list = [
    {
        "name" : "bla",
        "file" : "hier\und\da1.csv",
        ...
        "params" : [
            (parameter_list, 5),
            (parameter_list, 47),
...

for par, p in zip(paras, ['para1', 'para2', 'para3', 'para4']):
                    par[0][p] = row[par[1]]

BlackJack

@.robert: Bei solch verschachtelten Datenstrukturen sollte man IMHO ernsthaft über Klassen nachdenken.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Bei 'params' willst Du die Werte in den Tupeln direkt
verändern, daher solltet Du statt einer Liste von
Tupeln eine Liste von Listen nehmen.
Aber Du willst ja gar nicht die Tupelwerte direkt verändern,
sondern die in 'config_list' (Missverständis meinerseits),
daher obiger Code.

:wink:
yipyip
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

@BlackJack (und Nutten):
Jap, habe ich auch drüber auch gedacht. Allerdings habe ich mich dann dagegen entschieden, da ich damals dachte das es so genau so gut geht.
Nächste Woche werde ich ein wenig Zeit haben, da gucken ich mal ob ich da Gewinn raus ziehen kann, wenn ich das anders bastel. Im Moment war die erste Prämisse, da es läuft.

@yipyip:
Jo, danke, ich muss allerdings gestehen, das ich mittlerweile doch die Listen bevorzuge, da ich mir damit an anderer Stelle ein paar Abfragen erspare. :wink:


Mittlerweile läuft das Programm so wie es soll. Im Inneren ist es vielleicht nicht besonders hübsch, aber hinten kommt das richtige raus.
:)
Antworten