Seite 1 von 1

dict in dict

Verfasst: Dienstag 31. Mai 2022, 18:52
von Ernie1412
wie kriege ich aus eine Tabelle folgendes:

Code: Alles auswählen

daten={Arten:{"SuchZeit":{"XPath":"//div[@class='thumbsHolder elipsTxt']/div/div[@class='echThumb']//b[@class='tTm']",
                        },
                "SuchImage":{"XPath":"//div[@class='thumbsHolder elipsTxt']/div/div[@class='echThumb']/a/span/img",
                            "Attri":"data-original",
                        },
                "NummerID":{"XPath":"//div[@class='thumbsHolder elipsTxt']/div/div[@class='echThumb']/a[contains(@id,'videos')]",
                        },                
                "Regie":"",
                "Film":"",}}
eine HauptDictionaries "Arten"
eine unter Dictionaries, in meinem Fall ist das Zeile 0.
darin wieder ein Dictionaries Xpath, Attri usw.

wenn man mir nur zeigt, wie ich in ein dict ein dict packen kann, schaffe ich wohl den rest

Re: dict in dict

Verfasst: Dienstag 31. Mai 2022, 20:48
von __blackjack__
@Ernie1412: Einen Schlüssel-Wert-Paar einem Wörterbuch hinzufügen geht so: ``a_dictionary[key] = value``. Wobei `value` jedes beliebige Objekt sein kann. Also auch ein Wörterbuch. Alternativ wenn das Wörterbuch direkt als Literal erstellt werden kann, schreibt man ``a_dictionary = {key: value}``. Auch hier kann `value` wieder jedes beliebige Objekt sein. Also auch ein Wörterbuch.

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 11:04
von DeaD_EyE
Bei Arten fehlten die Anführungszeichen:

Code: Alles auswählen

daten = {
    'Arten': {
        'SuchZeit': {
            'XPath': "//div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']//b[@class='tTm']"
        },
        'SuchImage': {
            'XPath': "//div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']/a/span/img",
            'Attri': 'data-original'
        },
        'NummerID': {
            'XPath': "//div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']/a[contains(@id,'videos')]"
        },
        'Regie': '',
        'Film': ''
    }
}
Zugriff auf die zugewiesenen Werte von 'XPath':

Code: Alles auswählen

xpath_suchzeit = daten["Arten"]["SuchZeit"]["XPath"]
Oder über alle SubDicts iterieren und XPath ausgeben, wenn der Schlüssel vorhanden ist.

Code: Alles auswählen

xpath = "XPath"
for art, subdict in daten["Arten"].items():
    if xpath in subdict:
        print(f"{art:<10} -> {subdict[xpath]}")

Code: Alles auswählen

SuchZeit   -> //div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']//b[@class='tTm']
SuchImage  -> //div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']/a/span/img
NummerID   -> //div[@class='thumbsHolderelipsTxt']/div/div[@class='echThumb']/a[contains(@id,'videos')]
Am besten übst du das mal in der REPL.

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 12:46
von Ernie1412
ich habs schon hinbekommen:
ich will AUS einer TABELLE die Werte so das sie in dieses dict Muster passen.
und nicht wie ich den dict auslesen kann.

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 13:41
von Sirius3
Wie sieht denn Deine Tabelle aus? Welchen Code hast Du? Was passt daran nicht?

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 14:05
von DeaD_EyE
Ernie1412 hat geschrieben: Mittwoch 1. Juni 2022, 12:46 ich will AUS einer TABELLE die Werte so das sie in dieses dict Muster passen.
und nicht wie ich den dict auslesen kann.
Überlesen.
Wie ist nun deine Lösung?

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 15:11
von Ernie1412

Code: Alles auswählen

def webside_abspeichern(self):
        speichersatz={}
        webpage=self.lblWebside.text()    
        vertikal=[self.tblWdg_WebSides.verticalHeaderItem(r).text() for r in range(self.tblWdg_WebSides.rowCount())]
        horizontal=[self.tblWdg_WebSides.horizontalHeaderItem(r).text() for r in range(self.tblWdg_WebSides.columnCount())]        
        speichersatz=self.werte_eingabe(webpage,horizontal,vertikal)
        json_text = json.dumps(speichersatz, indent=4, ensure_ascii=False)
        print(json_text)

    def werte_eingabe(self,webpage,horizontal,vertikal):        
        speicher={}
        speichersatz={}
        spalte_0 = {}
        for zeile in range(len(vertikal)):    
            if self.tblWdg_WebSides.item(zeile, 1) is not None:                
                spalte_1bis8 = {}            
                for spalte, hori_header in enumerate(horizontal):                        
                    if self.tblWdg_WebSides.item(zeile, spalte) is not None:
                        spalte_1bis8[hori_header] =self.tblWdg_WebSides.item(zeile, spalte).text()           
                        name = f'{vertikal[zeile]}'
                        spalte_0[name] = spalte_1bis8
            else:
                name = f'{vertikal[zeile]}'
                spalte_0[name] = self.tblWdg_WebSides.item(zeile, 0).text()
        name = f'{webpage}'
        speicher[name]=spalte_0
        speichersatz=speicher[name]       
        return speichersatz
ich hab nur ein Problem:
speichern[name] zeigt er mir im debugger "{'startrek': {'Artist': {...}, 'Beschreibung': {...}, 'DateiOrdner': 'Y:\\_Labe...." an
speichersatz ist das ohne {'startrek':
Warum und wie kriege ich das da rein ?

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 16:02
von Ernie1412
antwort:
speichersatz[name]=spalte_0
return speichersatz

habs selber rausgefunden :)

diese ganzen Verschachtelungen da wirste bekloppt bei :)

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 17:02
von __blackjack__
@Ernie1412: Erstmal ein bisschen Englisch: Es heisst „website“ und nicht „webside“. Einzelne Seiten einer Website heissen „pages“ und nicht „sides“. Ich vermute da sind Fehler in der Namensgebung.

Der Wert der ersten Definition von `speichersatz` in `webside_speichern()` wird nirgends verwendet.

`r` ist ein ungewöhnlicher Name für einen Laufindex. Die erste Wahl ist da `i`.

Bei f"{webpage}" und f"{vertikal[zeile]}" sind die f-Zeichenkettenliterale sinnlos weil das schon Zeichenketten sind und da genau der gleiche Wert wieder bei raus kommt, denn man da rein gesteckt hat.

Man sollte Namen nicht zu weit von der Stelle entfernt definieren wo sie verwendet werden. Wenn man `speicher` und `speichersatz` in `werte_eingabe()` dahin verschiebt wo sie letztlich gebraucht werden, dann sieht das Ende der Methode so aus:

Code: Alles auswählen

        speicher = {}
        speicher[webpage] = spalte_0
        speichersatz = {}
        speichersatz = speicher[webpage]
        return speichersatz
Und hier sieht man das die erste Definition von `speichersatz` gar nicht gebraucht wird. Und das man `speicher` auch gleich als Literal hinschreiben kann, statt erst leer zu erstellen und dann einen Wert zu setzen:

Code: Alles auswählen

        speicher = {webpage: spalte_0}
        speichersatz = speicher[webpage]
        return speichersatz
Jetzt ist das aber total unsinnig erst ein Wörterbuch zu erstellen mit einem Schlüssel/Wert-Paar und dann diesen einen Wert da wieder heraus zu holen. Das ist ja letztlich einfach nur das hier:

Code: Alles auswählen

        return spalte_0
Beim Code zum füllen von `spalte_0` fällt eine Asymmetrie auf: in der inneren Schleife wird `enumerate()` verwendet, in der äusseren nicht. Das sollte dort auch verwendet werden.

Die Zuweisung von `spalte_1bis8` als Wert in `spalte_0` steht an der falschen Stelle. Dort wird das immer und immer wieder gemacht, obwohl es immer das gleiche `spalte_1bis8`-Wörterbuch ist.

Zwischenstand (ungetestet):

Code: Alles auswählen

    def werte_eingabe(self, webpage, horizontal, vertikal):
        spalte_0 = {}
        for zeile, vertical_header in enumerate(vertikal):
            if self.tblWdg_WebSides.item(zeile, 1) is not None:
                spalte_1bis8 = {}
                for spalte, horizontal_header in enumerate(horizontal):
                    item = self.tblWdg_WebSides.item(zeile, spalte)
                    if item is not None:
                        spalte_1bis8[horizontal_header] = item.text()

                if spalte_1bis8:
                    spalte_0[vertical_header] = spalte_1bis8
            else:
                spalte_0[vertical_header] = self.tblWdg_WebSides.item(
                    zeile, 0
                ).text()

        return {webpage: spalte_0}

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 17:53
von Ernie1412

Code: Alles auswählen

{webpage: spalte_0}
meinste auf sowas einfaches mit der geschweiften Klammer bin ich gekommen ? :)

Code: Alles auswählen

item = self.tblWdg_WebSides.item(zeile, spalte)
wenn man sich den code nochmals anschaut, is klar warum
auch das mit dem vertical_header

wegen dem Englischen: Vieles ist ja heute "denglisch". ich versteh das besser wenn ich deutsch mit englisch vermische. Wird ja heutzutage in der Jugendsparache auch so gemacht.
header weils im code öfters steht und nicht kopfzeile, das versteht keiner :)

aber danke für dein Einwand. hab den code nun verbessert :)

nur "if spalte_1bis8:" ist mir nicht klar. warum eine zusätzliche if Anweisung ?

Re: dict in dict

Verfasst: Mittwoch 1. Juni 2022, 21:00
von __blackjack__
@Ernie1412: Das ``if`` hatte ich weil an der Stelle wo die Zuweisung vorher stand sie ja nicht ausgeführt wurde wenn alle Elemente in der Zeile `None` gewesen wären. Ist natürlich quatsch weil der gesamte Code ja nur ausgeführt wird wenn an Index 1 das Element nicht `None` ist. Kann also weg die Bedingung.