Definieren eines dictionary elements aus variablen

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
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

Hallo zusammen,

ich habe in einer Liste jede Menge Strings in der folgenden Form:

Code: Alles auswählen

IR["gend"]="was"
Ich habe bereits den code, der mir dafür die drei Teile "IR", "gend" und "was" trennt und als einzelne Strings ausgibt.
Jetzt würde ich gerne daraus dictionaries bauen; das dict soll "IR" heißen, das Element "gend" und der Wert soll "was" sein, also:

Code: Alles auswählen

IR = dict()
IR['gend'] = 'was'
Wie mache ich das, da ja die Bezeichner aus variablen kommen?
Folgendes geht ja z.B. nicht, da ja sonst die Variable mit einem leeren dict() überschrieben wird:

Code: Alles auswählen

dictname = "IR"
element = "gend"
wert = "was"
dictname = dict()
Ich habe schon darüber nachgedacht das über vars() zu machen; mit Variablen geht das ja, aber da bin ich glaube ich auf dem Holzweg:

Code: Alles auswählen

>>> vars()['meine_variable'] = "mein_wert"
>>> meine_variable
u'mein_wert'
>>> vars()['dictname']['element'] = 'wert'
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: u'dictname'
Ich glaube ich stehe da böse auf dem Schlauch ...
Liffi
User
Beiträge: 153
Registriert: Montag 1. Januar 2007, 17:23

Du könntest das mit eval machen. Aber du solltest schon genau wissen, warum du das machen möchtest.
eval ist evil. Versuche lieber mal zu beschreiben, wofür du das benötigst.
sebastian0202
User
Beiträge: 168
Registriert: Montag 9. Mai 2016, 09:14
Wohnort: Berlin

Ich würde das eine Stufe höher abstrahieren.

all_used_dicts = {}

# deine funktion
all_used_dicts.update({dict_name: {element: value}})
print all_used_dicts[dict_name][element] # -> value

Es gibt aber auch die Möglichkeit ein Dictionary nach dem Value einer Variable zu erstellen.
Also eine Art dynamic dictionary name.
Aber von sowas würde die hier jeder abraten.
BlackJack

Dann rate ich auch noch mal explizit davon ab dynamisch Variablen erzeugen zu wollen. Dafür sind Wörterbücher da, also der Ansatz von sebastian0202, allerdings nicht mit `update()` was an der Stelle umständlich für eine einfache Zuweisung verwendet wird.
Pygoscelis papua
User
Beiträge: 206
Registriert: Freitag 13. März 2015, 18:36

also letztendlich so wahrscheinlich:

Code: Alles auswählen

dictname = "IR"
element = "gend"
wert = "was"
all_used_dicts = dict()
all_used_dicts[dictname] = dict()
all_used_dicts[dictname][element] = wert
verwendet man eigentlich für die zuweisung eher
"Dict = dict()" oder "Dict = {}" oder ist das egal?
import this
hidden python features

JAVA = Just Another Vulnerability Announcement :D
BlackJack

@Pygoscelis papua: Das ist egal. Wobei ich persönlich lieber `dict()` schreibe, weil man das nicht mit anderen Sachen wie leeren Listen oder Tupeln verwechseln kann wenn man nicht so genau hinschaut oder die Schrift klein und/oder die Schriftart nicht so gut ist, oder es fälschlicherweise für eine leere Menge halten kann.
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

Liffi hat geschrieben:Du könntest das mit eval machen. Aber du solltest schon genau wissen, warum du das machen möchtest.
eval ist evil. Versuche lieber mal zu beschreiben, wofür du das benötigst.
Hintegrund ist folgender:
Im bestehenden Prozess wird mit BASH-Scripten gearbeitet, welche so genannte "Config files" sourcen (. /pfad/file.conf), in welchen wiederum nur eine monströse Anzahl an Variablen und Arrays beschrieben wird. Diese Variablen/Arrays haben in den bestehenden Bash-Scripten alle eine feste, programmatische Funktion; es ist quasi eine Sammlung von hunderten von Parametern.

Da steht dann sowas hier drin:

Code: Alles auswählen

# project ID
PROJECTID="PIPAPO"

declare -A PIPAPOCONTEXT
PIPAPOCONTEXT["default"]="PIPAPODE"
PIPAPOCONTEXT["BATCH"]="PIPABATCH_EUROPE"
... Bash halt.
Jetzt soll das ganze nach und nach in Python Scripte überführt werden; damit der Regelbetrieb mit den bestehenden Bash-Scripten ohne anpassung des Workflows weiterlaufen kann, soll erst im zweiten Step darüber nachgedacht werden, wie man, mit dem Python Werkzeugkoffer bewaffnet, da etwas vernünftigereres etablieren kann.

Meine Herangehensweise ist hierbei daher mir einen "Bash -> Python" Wrapper zu schreiben, der die gleichen Dateien einlesen kann und daher nicht invasiv in den Workflow eingreift, bis "alles steht".
In diesem Beispiel soll nun aus dem "declare -A PIPAPOCONTEXT" - Bash code, welcher ja ein Bash (named) array erzeugt, ein Python Dictionary namens PIPAPOCONTEXT erzeugt werden. Die Zeilen darunter könnte man ja eigentlich so wie's ist als Python Code verwenden, da dieser ja, nachdem das Dict PIPAPOCONTEXT erzeugt wurde, ebenfalls mit PIPAPOCONTEXT["default"]="PIPAPODE" das Element "default" und dem Wert "PIPAPODE" dem Dict hinzugefügt würde.
Mir erschien es aber "sicherer" das stattdessen auseinander zu nehmen und zur weiteren Verarbeitung Variablen zuzuweisen.
Und da bin ich ja gerade.

Vor dem Hintergrund also: Was ist der Hintergrund davon, dass Ihr da fast geschlossen von abratet?
Mein Ziel ist es aus einem in Teilen unvorteilhaftem Konfig-Format die Daten einfach in Python - Elemente zu wandeln, damit ich es von da ausgehend "sauber" weiterverarbeiten kann.
BlackJack

@Judge: Man erzeugt halt nicht dynamisch Variablennamen. Das ist gefährlich und umständlich. Einfacher und ungefährlicher ist es das in eine Datenstruktur einzulesen. Die kann man dann auch leicht anders serialisieren, beispielsweise als JSON oder YAML.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Einen "Wrapper" zu bauen ist eine gute Idee. Das macht auch deutlich mehr Sinn als deine ursprüngliche Frage. Vermutlich gibt es für BASH auch schon vorhandene Module, auf die du aufbauen kannst. Leider kann ich keine empfehlen, weil ich das noch nicht selbst ausprobiert habe.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was spricht dagegen einfach Bottom-Up inkrementell Bash Skripte durch Python zu ersetzen? Du kannst problemlos von Bash aus Python Skripte aufrufen und somit ändern sich für den User auch überhaupt nichts. Zumindest bis du soweit bist dass das von den Bash Skripten nur noch Konfiguration übrig geblieben ist und ein bisschen Code der eine Python Anwendung aufruft. An dem Punkt führst du ein brauchbares Konfigurationsformat ein und verabschiedest dich komplett von Bash.
Benutzeravatar
Judge
User
Beiträge: 129
Registriert: Mittwoch 13. Juni 2012, 22:27
Wohnort: Ratingen
Kontaktdaten:

Kebap hat geschrieben:Einen "Wrapper" zu bauen ist eine gute Idee. Das macht auch deutlich mehr Sinn als deine ursprüngliche Frage. Vermutlich gibt es für BASH auch schon vorhandene Module, auf die du aufbauen kannst. Leider kann ich keine empfehlen, weil ich das noch nicht selbst ausprobiert habe.
Aber - meine ursprüngliche Frage war doch ein Teil des entstehendem Wrappers? O.o
DasIch hat geschrieben:Was spricht dagegen einfach Bottom-Up inkrementell Bash Skripte durch Python zu ersetzen? Du kannst problemlos von Bash aus Python Skripte aufrufen und somit ändern sich für den User auch überhaupt nichts. Zumindest bis du soweit bist dass das von den Bash Skripten nur noch Konfiguration übrig geblieben ist und ein bisschen Code der eine Python Anwendung aufruft. An dem Punkt führst du ein brauchbares Konfigurationsformat ein und verabschiedest dich komplett von Bash.
Du meinst: Das man das ursprüngliche Bash - Script durch ein nahezu leeres ersetzt, welches nur diese Konfig einliest (welche Umgebungsparameter setzt) , die Aufrufparameter an das Python Script durchreicht und das Python Script aufruft, welches dann wiederum die gesetzten Umgebungsvariablen einliest?
Damit hätte ich doch nicht wirklich etwas gegenüber des gerade laufenden Ansatzes gewonnen; ob ich die Daten nun aus einer Textdatei oder aus Umgebungsvariablen zusammensuche, ist doch gehoppst wie gesprungen. Bei der Config-Datei habe ich wenigstens noch den Vorteil das ich dabei einfach iterierbare Objekte (nämlich Zeilen) habe, über die ich arbeiten kann.

Oder verstehe ich Dich da falsch?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Judge: Du solltest Dir vielleicht jetzt schon Gedanken darüber machen, in welchem Format Deine Konfigurationsdateien zum Schluß vorliegen sollen. Dann kannst Du Deinen Wrapper jetzt schon mit dem selben Interface schreiben und mußt hinterher nicht nochmal Dein Python-Programm umschreiben oder wieder einen Wrapper um irgendeine Standardbibliothek schreiben. Bei json/yaml wären das verschachtelte Wörterbücher, bei cfg/ini dagegen Klassen, die einen Zugriff auf Sections und Keys kapseln.
Antworten