Stichworte und Beschreibungen

Du hast eine Idee für ein Projekt?
Antworten
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Hallo Leute,

ich suche eine Datenstruktur, um ausführliche Beschreibungen einzelner Stichworte zu sammeln, zu ergänzen und letztendlich auch übersichtlich darzustellen. Hier habe ich irgendwie ein bisschen ein Brett vor dem Kopf.

Meine erste Idee war ein Wörterbuch. Mein Problem ist, dass ich am Anfang noch nicht weiß, welche Stichworte insgesamt vorliegen werden. Diese werden erst nach und nach ergänzt. Zudem können verschiedene Stichworte dieselbe Beschreibung haben. Leider kann ich im Wörterbuch ja keine Liste als Schlüsselwert benutzen, die dann nach und nach erweitert wird, sonst könnte ich es mir bspw. so vorstellen:

Code: Alles auswählen

beschreibungen = {
    "auto": "Ein Auto besteht aus vier Reifen und einer Fahrgastzelle, sowie vielen weiteren Details, die meist unter der Haube des Wagens verborgen bleiben.",
    "reifen": "blabla",
    "fahrgastzelle": "blablabla"
}
Zu diesem Zeitpunkt stellt sich dann raus, dass das Stichwort "wagen" ebenfalls den gleichen Beschreibungstext wie "auto" haben soll. Wie kann ich das aber ergänzen? So ja nun leider nicht:

Code: Alles auswählen

beschreibungen = {
    ["auto", "wagen"]: "Ein Auto ..."}
Ich möchte aber auch ungerne beide Stichworte einzeln mit komplett identischer Beschreibung aufnehmen, da diese mitunter länger ausfallen können.


Frage 2:
Wie kann ich ein grafisches Netzwerk dieser Stichworte sammeln und übersichtlich darstellen? Man sieht am Beispiel oben, dass "reifen" und "fahrgastzelle" in dem Beschreibungstext von "auto" vorkommen. Eine denkbare Struktur wäre also:

Code: Alles auswählen

- auto
-- reifen
-- fahrgastzelle
Vielleicht übersehe ich noch Zusammenhänge, aber das scheint halbwegs einfach?
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.
BlackJack

@Kebap: Du könntest unter 'wagen' den Text 'siehe "auto"' hinterlegen, oder doch den *selben* Text wie bei 'auto' verwenden, also das selbe `str`-Objekt. Ansonsten gehen Tupel als Schlüssel. Du kannst also ``{('auto', 'wagen'): '...'}`` anlegen. Dann lässt sich aber schlecht(er) nach 'auto' oder 'wagen' einzeln nachschlagen.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

@BlackJack: Danke. Ich möchte es vermeiden, mehrfach das *selben* 'str'-Objekt zu verwenden, da es sehr viele Texte werden könnten, und ich diese irgendwie speichern muss, würden Mehrfachnennungen den Speicherplatz vermutlich unnötig aufblähen.

Wenn ich Tupel verwenden würde, könnte das vielleicht funktionieren. Das macht die Handhabung komplizierter, darüber muss ich noch nachdenken.

Ich würde ja beginnen mit ``{'auto': '...'}`` oder zwecks einheitlicher Handhabung vielleicht direkt ``{('auto',): '...'}`` und dann erst etwas später auf 'wagen' stoßen. Das heißt, ich müsste dann das ursprüngliche Schlüssel/Wert-Paar rauswerfen und mit dem neu erweiterten Tupel erneut ins Wörterbuch eintragen. Hmm, werde ich mal ausprobieren, vielleicht funktioniert das halbwegs angenehm.


Zur Verdeutlichung von Frage 2:

Ich möchte eine übersichtliche Darstellung aller Stichworte erreichen, die ich bspw. im Browser darstellen kann, klickbar gestalten, so dass ich dann den jeweiligen Beschreibungstext sehe. Bestenfalls sollen die Zusammenhänge der Stichworte abgebildet werden, da sie ja keine flache Liste bilden, sondern mehr eine Hierarchie wie im folgenden Beispiel zu sehen... wobei durchaus auch seltsame Schlaufen auftreten könnten. Gibt es dazu empfehlenswerte Module? Welche Datenstruktur könnte benutzt werden?

Code: Alles auswählen

- Book project
-- Research
--- Data collection
-- Writing
...
Bild
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.
BlackJack

@Kebap: Mehrfach das *selbe* `str`-Object belegt *einmal* Speicher, denn das ist ja immer der *selbe* Speicher beim *selben* Objekt. Anders ist das bei `str`-Objekten die nur inhaltlich *gleich* aber nicht *die selben* sind. Man müsste natürlich darauf achten, dass gleicher Inhalt auch immer das *selbe* Objekt in der Datenstruktur bedeutet.

Am besten wahrscheinlich über eine Indirektion, also nicht den Text als Wert speichern, sondern ein Objekt das den Text als Attribut hat. An das Objekt kann man dann auch gleich Synonyme und die Verweise auf Worte aus dem Text hängen.

Du hast hier keine Hierarchie, also einen Baum, sondern einen Graphen.

Die Datenstruktur hängt letztlich davon ab wie Du damit arbeiten musst. Wenn Du beispielsweise (effizient) nach Einzelbegriffen suchen können musst, dann macht ein Wörterbuch das Tupel von Begriffen auf die Beschreibung abbildet keinen Sinn. Denn dann müsste man ja sequentiell alle Schlüssel durchsuchen.
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

Das Vorgehen mit Verweisen, so ähnlich wie BlackJack es beschreibt, ist beispielsweise bei kontrollierten Vokabularien zu finden. Du definierst dir einen Basis Begriff (also etwa "Auto") und hast dann Verweisungsformen (z.B. "Wagen), die auf diese ... äh... verweisen. Das kannst du ja zum Beispiel so lösen, dass die Werte typisiert sind, also entweder Literale oder Verweise auf andere Schlüssel sein können, die du dann im Dictionary suchst. M.m.n. ist es sinnvoller, das konzeptuell anständig umzusetzen, als sich da über die effizienteste Datenstruktur Gedanken zu machen, die ja auch austauschbar sein kann (wenn du zum Beispiel irgendwann eine Datenbank verwenden möchtest). Je nach dem, welche Ambitionen du mit deinem Vorhaben hast, könntest du auch mal in die akademische Ansätze, die es dazu gibt, reinschauen (z.B. SKOS) -- für den einfachen Hausgebrauch natürlich eher nicht.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

@Blackjack: Danke für den Hinweis auf Graphen. Mit der Graphentheorie hatte ich mich noch nicht groß beschäftigt, scheint aber interessant und passend. Daher habe ich mich da etwas eingelesen und das unten genannte Programm nach Anleitung (inf-schule.de) gebastelt, um anschließend zeichnen zu können. Mit String-Knoten wie "A" funktioniert das bereits halbwegs gut, so dass ich demnächst die Strings durch Knoten-Objekte ersetzen möchte, die dann auch einen zweiten String, sowie ggf. Synonyme usw. beinhalten. Wobei das nicht ganz zum original Konzept passt, da die Synonyme ja eigentlich gleichwertig sind, und nicht eins als "Hauptbegriff" und die anderen als ihm zugeordnet gelten. Aber ich fürchte, ich verzettele mich da vielleicht auch schon etwas an einem Nebenschauplatz. Mir ging es auch darum, später beim *Speichern* der Daten nicht zu oft den *selben* Text zu speichern, nur weil er bei verschiedenen Synonymen vorkommt.


@nezzcarth: Ja, es geht hier eher um den Hausgebrauch, aber danke für die Anregungen und Fachbegriffe, die ich für weitere Inspiration benutze. Tatsächlich scheint das auch ein interessantes Forschungsfeld zu sein. Zum Ratschlag, das "konzeptuell anständig umzusetzen" fand ich leider wenige Suchtreffer - und genau damit tue ich mich derzeit extrem schwer! Wo finde ich Anleitungen dazu, welche konzetionellen Arbeiten sinnvoll wären? Diese Frage stellt sich mir in vielen Projekten...! :K

Hier dachte ich ja spontan, weil ich ja schon weiß, welche Daten ich bearbeiten möchte, dann wäre die Wahl einer passenden Datenstruktur doch ein wertvoller nächster Schritt. Nicht wegen Effizienz, sondern um die Entwicklung voranzutreiben. Aber du hast Recht, sie könnte sich in Zukunft auch ändern, und über das Speichern in einer Datenbank habe ich auch bereits nachgedacht. Damit kenne ich mich auch noch nicht gut genug aus.


Nachfolgend der aktuelle Code in einer Umbauphase, gerade wurde er umgestellt. Vorher war Graph.knotenliste = ["A", "B", "C", "D"] und damit funktionieren auch die assert, jetzt mit dem neuen Knoten-Objekt aber nicht mehr, weshalb ich einige Hürden überspringen muss, die den Code unübersichtlich machen.

Kann ich die Knoten-Klasse so gestalten, dass sie nach außen hin weiter wie ein String verhält? Z.B. bei """if "A" in ["A", "B", "C", "D"]""" kam vorher True, jetzt natürlich erstmal ValueError, weil mein Klassenobjekt nicht "A" ist... :(

Code: Alles auswählen

# Angelehnt an http://www.inf-schule.de/algorithmen/graphen/implementierung/

class Knoten(object):
    def __init__(self, name, beschreibung = None):
        self.name = name
        self.beschreibung = beschreibung
        self.synonyme = []

    def __str__(self):
        return self.name

    def __repr__(self):
        return "'%s'" % self.name

    def hat_synonyme(self):
        return len(self.synonyme) > 0

    def add_synonym(self, name):
        if name not in self.synonyme:
            self.synonyme.append(name)
        else:
            raise ValueError("Synonym bereits bekannt.")


class Graph(object):
    def __init__(self, knotenliste = None, adjazenzmatrix = None):
        if knotenliste:
            self.knotenliste = knotenliste
        else:
            self.knotenliste = [
                Knoten("A", "Der erste Buchstabe des Alphabets."),
                Knoten("B", "Der zweite Buchstabe des Alphabets."),
                Knoten("C", "Der dritte Buchstabe des Alphabets."),
                Knoten("D", "Der vierte Buchstabe des Alphabets.")
            ]

        if adjazenzmatrix:
            self.adjazenzmatrix = adjazenzmatrix
        else:
            self.adjazenzmatrix = [
                [0, 1, 0, 0],
                [0, 1, 1, 1],
                [1, 1, 0, 0],
                [0, 0, 0, 0]
            ]

        # Alternative Implementierung, noch nicht weiter betrachtet:
        #self.adjazenzliste = [
        #    ["A", ["B"]],
        #    ["B", ["A", "B", "C"]],
        #    ["C", ["A", "B"]],
        #    ["D", []]
        #]


    def alle_knoten(self):
        return self.knotenliste

    def existiert_knoten(self, knoten):
        for k in self.knotenliste:
            if knoten == k.name:
                return True
        return False

    def add_knoten(self, knoten):
        if not self.existiert_knoten(knoten):
            self.adjazenzmatrix.append([0] * len(self.knotenliste))
            for zeile in self.adjazenzmatrix:
                zeile.append(0)
            self.knotenliste.append(knoten)
        else:
            raise ValueError("Der Knoten '%s' existiert bereits." % knoten)

    def del_knoten(self, knoten):
        if self.existiert_knoten(knoten):
            position = self.knotenliste.index(knoten)
            self.adjazenzmatrix.pop(position)
            for zeile in self.adjazenzmatrix:
                zeile.pop(position)
            self.knotenliste.remove(knoten)
        else:
            raise IndexError("Der Knoten '%s' existiert nicht." % knoten)

    def existiert_kante(self, startknoten, endknoten):
        for k in (startknoten, endknoten):
            if not self.existiert_knoten(k):
                return False

        x = self.knotenliste.index(startknoten)
        y = self.knotenliste.index(endknoten)
        return self.adjazenzmatrix[x][y] > 0

    def add_kante(self, startknoten, endknoten):
        if not self.existiert_kante(startknoten, endknoten):
            start_position = self.knotenliste.index(startknoten)
            end_position = self.knotenliste.index(endknoten)
            self.adjazenzmatrix[start_position][end_position] = 1
        else:
            raise ValueError("Die Kante von '%s' nach '%s' existiert bereits." %
                             (startknoten, endknoten))

    def del_kante(self, startknoten, endknoten):
        if self.existiert_kante(startknoten, endknoten):
            start_position = self.knotenliste.index(startknoten)
            end_position = self.knotenliste.index(endknoten)
            self.adjazenzmatrix[start_position][end_position] = 0
        else:
            raise IndexError("Die Kante von '%s' nach '%s' existiert nicht." %
                             (startknoten, endknoten))

    def alle_nachbarn(self, knoten):
        nachbarn = [k for k in self.knotenliste if
                    self.existiert_kante(knoten, k)]
        return nachbarn


def test():
    Mein_Graph = Graph()

    assert Mein_Graph.existiert_knoten("D") == True
    assert Mein_Graph.existiert_knoten("G") == False

    assert Mein_Graph.existiert_kante("A", "D") == False
    assert Mein_Graph.existiert_kante("B", "D") == True
    assert Mein_Graph.existiert_kante("X", "Y") == False

    assert Mein_Graph.alle_nachbarn("B") == ['B', 'C', 'D']

    knotenliste_vorher =  Mein_Graph.knotenliste[:]
    adjazenzmatrix_vorher = Mein_Graph.adjazenzmatrix[:]
    Mein_Graph.add_knoten("X")
    Mein_Graph.add_kante("X", "D")
    Mein_Graph.del_kante("X", "D")
    Mein_Graph.del_knoten("X")
    assert Mein_Graph.knotenliste == knotenliste_vorher
    assert Mein_Graph.adjazenzmatrix == adjazenzmatrix_vorher

def test2():
    print "\nAdding Knoten 'X'"
    Mein_Graph.add_knoten("X")
    print "Knotenliste: {}".format(Mein_Graph.knotenliste)
    print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)

    print "\nAdding Kante ('B', 'X')"
    Mein_Graph.add_kante("B", "X")
    print "Knotenliste: {}".format(Mein_Graph.knotenliste)
    print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)

    print "\nDeleting Kante ('X', 'D')"
    Mein_Graph.del_kante("X", "D")
    print "Knotenliste: {}".format(Mein_Graph.knotenliste)
    print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)

    print "\nDeleting Knoten 'C'"
    Mein_Graph.del_knoten("C")
    print "Knotenliste: {}".format(Mein_Graph.knotenliste)
    print "Nachbarmatrix: {}".format(Mein_Graph.adjazenzmatrix)


if __name__ == '__main__':
    test()

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.
BlackJack

@Kebap: *Speichern* ist ja noch einmal eine andere Baustelle. Da könnte man beispielsweise alle Daten die von mehr als einem Knoten referenziert werden nur einmal speichern und dabei IDs vergeben. Und an der Stelle wo die Daten stehen würden, dann die IDs speichern. Und bei den Synonymen kann man die auch getrennt *einmal* speichern. Im Speicher wäre es dann aber schon sinnvoll wenn jedes Wort mit all seinen Synonymen verbunden ist.

Man kann zwar das Knotenobjekt so gestalten das man es mit Zeichenketten vergleichen kann, also ``node in ['A', 'B', 'C']`` funktioniert, aber eigentlich will man eher die Knoten so gestalten das man sie mit Knoten vergleichen kann, also in der Liste ebenfalls Knoten sind. Sonst bekommt man IMHO unnötige indirektionen weil man bei einer Liste mit Zeichenketten dazu dann ja erst wieder die Knoten ermitteln muss. Allerdings hängt das auch davon ab was man mit diesen Daten machen will. Das ist der Grund warum es keine allgemeine Graphimplementierung in der Standardbibliothek gibt: jeder braucht die am Ende doch etwas anders.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

BlackJack hat geschrieben:Man kann zwar das Knotenobjekt so gestalten das man es mit Zeichenketten vergleichen kann, also ``node in ['A', 'B', 'C']`` funktioniert, aber eigentlich will man eher die Knoten so gestalten das man sie mit Knoten vergleichen kann, also in der Liste ebenfalls Knoten sind.
Genau, in der Liste sind Knoten. Sorry, wenn das etwas missverständlich war.

Aber ich habe dann ja ein neues Stichwort, und möchte wissen, ob es dazu schon einen Knoten gibt. Also habe ich quasi ``"A" in [node1, node2, node3]`` und das funktioniert nicht mehr.

Ich müsste vermutlich eine neue Liste erstellen mit nur den Namen der Knoten (plus ggf. noch weiteren Synonymen) und dann dagegen prüfen.

"Machen" möchte ich mit diesen Daten noch nicht allzu viel besonderes, außer sie erstmal zu sammeln, übersichtlich darzustellen, ggf. durchsuchbar zu gestalten und insb. fehlende Stichworte immer wieder nachträglich ergänzen.

Es soll dann auch mehrere unabhängige Graphen geben, jeder mit seinem eigenen Strauß an Stichworten und Beschreibungen.
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.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Ich würde es vom Wort ableiten und um bei Auto und Wagen zu bleiben, steht ja ein Wagen zwei bis drei Stufen über einem Auto, da bereits in den ersten Hochkulturen Wagen anzutreffen waren. Oben Wagen, darunter Wagentyp, ob zweirädriger oder vierrädriger, darunter Einsatzzweck, ob Streitwagen der Ägypter oder selbstfahrender Wagen zur Beförderung von Personen. Eventuell noch mehr Zwischenstufen. Und nur bei Überschneidungen die passenden Texte einblenden.

Vorbild könnte eine Taxonomie sein, dann hat jede Stufe eine eigene Beschreibung und ein Teil dieser Beschreibung ließe sich gemeinsam verwenden.

https://de.wikipedia.org/wiki/Taxonomie

War nur so ein Gedanke, der aufwendig umzusetzen wäre, insofern es sich nicht um ein eingeschränktes Themengebiet handeln sollte.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Was mir noch eingefallen ist, dass Ding hatte ich im letztem Jahr benutzt, um weitere verwandte Begriffe zu finden, nur das eigentliche Online-Tool ist nicht mehr erreichbar, doch das Script liegt hier scheinbar noch herum. Ich gehe davon aus, dass sich das nur nach der internen Verlinkung und den Positionen von Querverweisen richtete.

https://github.com/nyfelix/wikimindmap

Und bei Wagen, na ja, obwohl der Begriff nur als Beispiel dienen sollte, doch wenn Du oben mit Attributen beginnst, dann halt stufenweise und die Beschreibung für jedes Attribut könntest Du in einer Datenbank ablegen.

Erste Stufe - Wagen:
Attribut: Fortbewegung
Attribut: Transport

Zweite Stufe - Antriebsarten:
Attribut: Muskelkraft
Attribut: Maschinell

Falls maschinell, so weitere Attribute wie, Dampf, Benzin, Diesel, Elektro.

So ließe sich das nach unten immer weiter auffächern und alles was umgekehrt auf dem Weg bis zum Wurzelknoten liegen würde, sollte sich mehr oder weniger verwenden lassen. In einem Graphen sollte sich das ähnlich darstellen lassen, könnte ich mir zumindest vorstellen, habe aber bisher noch nie einen programmiert.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

@Melewo: Danke für deine Anmerkungen, aber sie gehen leider an meiner Situation vorbei. Bei mir ist es so, dass ich die Stichworte und Beschreibungen vorgegeben bekomme. - Meine Aufgabe ist hier also (oder so denke ich mir), diese Texte aufzunehmen, übersichtlich darzustellen und leichter überprüfbar zu machen.

Vielleicht sollte ich aber mal erst mit einer flacheren Liste und ohne Synonyme anfangen, denn dieses Graphenzeichnen ist ja wieder eine Wissenschaft für sich und ich brauche neue Python Module, usw.
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.
Benutzeravatar
Kebap
User
Beiträge: 686
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Ich bin nicht sicher, ob ich den Hinweis auf "dasselbe str-Objekt" richtig verstanden habe. Es reicht ja nicht nur der gleiche Inhalt an zwei verschiedenen Stellen wie "hier" und "hier" - das wären zwei verschiedene Objekte, richtig? Also Indirektion.

Nach meinem naiven Verständnis müsste meine Datenstruktur wie folgt aussehen, um schnellen Zugriff auf die Beschreibung eines einzelnen Stichwortes zu erhalten. Ein Objekt gruppiert alle Infos. Ein Wörterbuch liefert die Beschreibung zum eingegebenen Stichwort.

Zusätzlich möchte ich zu dem Zeitpunkt gern auch alle anderen Stichworte mit der gleichen Beschreibung kennen. Benötige ich dazu eine weitere Datenstruktur? Die ich dann ebenfalls synchron halten muss? Oder bin ich schneller, sie spontan zu erstellen? Werde ich wohl ausprobieren müssen, ob dort überhaupt Unterschiede auftreten. Erstmal nebensächlich.

Unklar ist mir auch noch, wie ich mit Python am besten solche mehrzeiligen Texte speichern und wieder einlesen kann. Erstmal fällt mir CSV ein, wobei ich unsicher bin, ob das immer einwandfrei funktioniert. Bin offen für bessere Vorschläge

Zur Visualisierung ist mir nun vis.js vor die Füße geschwemmt worden. Nicht sicher, ob das richtig dimensioniert ist. Sieht aber erstmal ansprechend aus. Was meint ihr?
Andererseits sind die Verbindungen zwischen einzelnen Stichworten doch nicht immer so zwangsläufig und eindeutig, wie das in den dortigen Graphen gezeigt wird. Ich brauche also definitiv eine Eingabebox für frei wählbare Stichworte und kann nicht nur mit der Maus arbeiten.

Hier mein jüngster Entwurf:

Code: Alles auswählen

# Datenstruktur
Objekt bla:
  bla.stichworte = ["bla", "bla2", "bla3"]
  bla.beschreibung = "Gern auch\n mehrzeilig"

# Liste aller bekannten Informationen
objekte = [
  bla,
  foo,
  bar,
  baz
]

# Wörterbuch zum schnellen Suchen und Finden
stichworte = {
	"bla": bla.beschreibung,
	"bla2": bla.beschreibung,
	"bla3": bla.beschreibung,
	"foo": foo.beschreibung,
	"bar": bar.beschreibung,
	"bar2": bar.beschreibung,
	"baz": baz.beschreibung
}


# Beispielhafter Ablauf in der Bedienung
Eingabe: 
  "bla2"

Ausgabe:
  "bla", "bla2", "bla3"
  bla.beschreibung

# Beispielhafter Aufbau der gepeicherten Textdatei:
"bla", "bla2", "bla3"
"Gern auch 
 mehrzeilig"
-----
"foo"
"Foo Beschreibung hier"
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.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Yaml kann Referenzen speichern:

Code: Alles auswählen

import yaml

bla = (['bla','bla2','bla3'], "Beschreibung bla")
foo = (['foo','foo-bar'], "Beschreibung foo")

stichworte = {}
for stichwort in bla[0]:
    stichworte[stichwort] = bla
for stichwort in foo[0]:
    stichworte[stichwort] = foo

print(stichworte)
# {'bla3': (['bla', 'bla2', 'bla3'], 'Beschreibung bla'), 'bla2': (['bla', 'bla2', 'bla3'], 'Beschreibung bla'), 'bla': (['bla', 'bla2', 'bla3'], 'Beschreibung bla'), 'foo': (['foo', 'foo-bar'], 'Beschreibung foo'), 'foo-bar': (['foo', 'foo-bar'], 'Beschreibung foo')}

yaml.dump(stichworte, sys.stdout)
# bla: &id001 !!python/tuple
# - [bla, bla2, bla3]
# - Beschreibung bla
# bla2: *id001
# bla3: *id001
# foo: &id002 !!python/tuple
# - [foo, foo-bar]
# - Beschreibung foo
# foo-bar: *id002
Antworten