Seite 1 von 1

Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 18:15
von machupicchu
Hi, ich möchte eine zwei dictionaries sortieren und diese ausgeben.

Ich habe zwei dicts die ich vergleichen möchte:

Liste 1
D = {'Tel': '01634498766', 'Addresse': 'Berlinerallee 19', 'User': 'Max', 'ID': '111'}
Liste 2
B = D = {'Tel': '01634498766', 'User': 'Max', 'ID': '111'}
Ich möchte folgende Ausgabe erreichen:

Code: Alles auswählen

Tel: 01634498766                    Tel: 01634498766  
Adresse: Berlinerallee 19
User: Max                               User: Max
ID: 111                                  ID: 111

Kann mir da vlt jemand helfen??

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 18:23
von BlackJack
@machupicchu: Wörterbücher selbst kann man nicht sortieren weil die Datenstruktur das nicht hergibt. Man kann die Schlüssel/Wert-Paare aber zum Beispiel als Liste sortieren. Oder man hat eine bereits sortierte Liste an Schlüsseln, die man dann in der Reihenfolge von den Wörterbüchern abfragt. Das ist wohl der Weg den man zusammen mit dem Vergleichen von den beiden Wörterbüchern nehmen würde. Entweder kennst Du die Werte für die Schlüssel und kannst die im Programm hinterlegen, oder Du bestimmst die Vereinigungsenge der Schlüssel aus beiden Wörterbüchern und fragst die dann von beiden ab.

Code: Alles auswählen

#!/usr/bin/env python


def main():
    record_a = {
        'Tel': '01634498766',
        'Addresse': 'Berlinerallee 19',
        'User': 'Max',
        'ID': '111'
    }
    record_b = {'Tel': '01634498766', 'User': 'Max', 'ID': '111'}
    for key in set(record_a.iterkeys()) | set(record_b.iterkeys()):
        value_a, value_b = (r.get(key) for r in [record_a, record_b])
        print '{0:10s}{1:30s}{2:30s}{3}'.format(
            key, value_a, value_b, value_a == value_b
        )


if __name__ == '__main__':
    main()

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 21:52
von machupicchu
Super danke "blackjack"

Hätte da noch eine Frage. Kann man den code auch irgendwie für stringliste anwenden?
list1 list2

Tel Tel
Addresse None
User User
ID ID
Habe es mal so versucht, aber leider nicht geklappt. :|

Code: Alles auswählen

for key in set(list1) | set(list2):
        value_a, value_b = (r.???? for r in [list1, list2])
        print '{0:10s}{1:30s}{2:30s}{3}'.format( ????, value_a, value_b, value_a == value_b
        )

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:02
von BlackJack
@machupicchu: Das macht doch überhaupt keinen Sinn‽ Listen haben keine Schlüssel die auf Werte abgebildet werden. Also da wo Deine Fragezeichen stehen, was sollte denn da dann stehen wenn es keine Schlüssel gibt?

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:13
von machupicchu
Das ist richtig! Ich versuche halt diesen code in mein programm einzubauen.
Ich möchte mein xml tag auflisten und das erhalte ich als stringtext, wenn ich mich nicht irre.

Ich sage in meinem code:

Code: Alles auswählen

for element1, element2 in zip(tree1.iter(), tree2.iter()):
      print element1.tag, element2.tag
Ausgabe:

Tel Tel
Addresse User
User ID
ID Preis

Gewünschte Ausgabe:


Tel Tel
Addresse None
User User
ID ID
Wenn ich ein element lösche, dann verschiebt sich die reihenfolge. Das ist halt mein problem in der ganzen geschichte.
Ich möchte nun erreichen, dass meine Ausgabe wie im dictionary aussieht.

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:20
von Hyperion
Wenn Du einen XML-Parser verwendest, dann bekommst Du Objekte von Knoten... nix mit Strings!

Und villeicht wäre es hilfreich, wenn Du mal die Struktur und die gewünschte Form nennen und beschreiben könntest. Also welcher Knoteninhalt soll wie und wo mit welcher anderen Information gruppiert oder ausgegeben werden.

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:40
von BlackJack
@machupicchu: Ich rate jetzt einfach mal, dass das was Du vorhast nicht geht, oder zumindest sehr aufwändig wird, und damit dann ganz bestimmt jenseits von Deinen momentanen Fähigkeiten liegt.

Wenn man die beiden XML-Elementbäume aus Deiner Beispielausgabe „flachklopft”, haben die offensichtlich nicht die gleiche Struktur oder zumindest nicht die gleiche Reihenfolge und es können offensichtlich auch Elemente eingefügt/gelöscht sein. So allgemein behaupte ich mal, dass man das gar nicht zuverlässig angleichen kann, ohne auch Gefahr zu laufen es falsch anzugleichen.

Ich habe es ja schon mal an anderer Stelle geschrieben: Hör auf das XML so total allgemein zu verarbeiten und operiere gezielt auf der Struktur und mit den Elementnamen der konkreten XML-Anwendung die Du vorliegen hast. Dafür gibt es die Elementnamen und die Struktur doch, damit man eben kein flaches Dateiformat hat, sondern verschachtelte Strukturen mit eindeutig benannten Teilstrukturen, welche man über Namen und Pfade selektieren kann.

Schreibe eine Funktion die über alle Teilbäume iteriert, die eine Adresse repräsentieren. Und dann eine Funktion die aus so einem Teilbaum, der ja offenbar semantisch so etwas wie Schlüssel/Wert-Paare modelliert, ein Wörterbuch mit diesen Daten erstellt. Dann kannst Du eine Funktion schreiben, die zwei solcher Wörterbücher vergleicht. Teile das grosse Problem in kleinere Teilprobleme und die auch wieder in Teilprobleme, bis die einzelnen Probleme so klein und übersichtlich sind, dass man sie Lösen kann. Und die Teillösungen setzt man dann zu grösseren Lösungen zusammen, bis man eine komplette Lösung für das Ausgangsproblem hat. Und wirf dabei keine Information weg die wichtig ist, wie das Ignorieren der Struktur die in der XML-Datei vorhanden ist um sich daran zu orientieren.

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:41
von machupicchu
Ich parse bereits meine xml datei. Mit dem code von "blackjack" kann ich die attribute beider dateien vergleichen.

Code: Alles auswählen

<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
    <Address >
        <Name>Ellen Adams</Name>
        <Street>123 Maple Street</Street>
        <City>Mill Valley</City>
        <State>CA</State>
        <Zip>10999</Zip>
     --- hier gelöscht -----
    </Address>
    <Address Type="Billing">
        <Name>Tai Yee</Name>
        <Street>8 Oak Avenue</Street>
        <City>Old Town</City>
        <State>PA</State>
        <Zip>95819</Zip>
        <Country>USA</Country>
    </Address>
    <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
    <Items>
        <Item PartNumber="872-AA">
            <ProductName>Lawnmower</ProductName>
            <Quantity>1</Quantity>
            <USPrice>148.95</USPrice>
            <Comment>Confirm this is electric</Comment>
        </Item>
    </Items>
</PurchaseOrder>

Code: Alles auswählen

<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
    <Address >
        <Name>Ellen Adams</Name>
        <Street>123 Maple Street</Street>
        <City>Mill Valley</City>
        <State>CA</State>
        <Zip>10999</Zip>
        <Country>USA</Country>
    </Address>
    <Address Type="Billing">
        <Name>Tai Yee</Name>
        <Street>8 Oak Avenue</Street>
        <City>Old Town</City>
        <State>PA</State>
        <Zip>95819</Zip>
        <Country>USA</Country>
    </Address>
    <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
    <Items>
        <Item PartNumber="872-AA">
            <ProductName>Lawnmower</ProductName>
            <Quantity>1</Quantity>
            <USPrice>148.95</USPrice>
            <Comment>Confirm this is electric</Comment>
        </Item>
        <Item PartNumber="926-AA">
            <ProductName>Baby Monitor</ProductName>
            <Quantity>2</Quantity>
            <USPrice>39.98</USPrice>
            <ShipDate>1999-05-21</ShipDate>
        </Item>
    </Items>
</PurchaseOrder>
Der code gibt die attribute mit den werten aus. Nun, habe ich bei den elementen probleme mit der reihenfolge, sobald ich ein element lösche.
Bei den Attributen hatte es mit dem code funktioniert, da es in einem dictionary war.
Das problem mit den elementen möchte ich so ähnlich umsetzen, wie mit den attributen. Hoffe das reicht fürs verständnis aus????



Ausgabe:

PurchaseOrderNumber 99503 99503 True
OrderDate 1999-10-20 1999-10-20 True
Type Billing None False
Type None Billing False
PartNumber 872-AA None False
PartNumber None 872-AA False
PartNumber 926-AA None False
PartNumber None 926-AA False

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 22:54
von BlackJack
@machupicchu: Logischerweise vergleichst Du die falschen Elemente miteinander wenn die beiden Dateien nicht die gleichen Elemente enthalten. Ab dem Element wo im ersten Dokument das Land fehlt wird falsch verglichen. Du musst halt wie schon gesagt die Struktur berücksichtigen.

Was soll denn hier eigentlich gelöst werden? Also ganz allgemein die Problembeschreibung? Was sind das für Daten? *Warum* willst Du die vergleichen? Was ist der Sinn von dem Ganzen?

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 23:11
von machupicchu
Warum ich das mache? Ist für einen automatisierten test. Jetzt aber bitte nicht fragen, warum für einen automatisierten test.
Mit dem code will ich alle attribute und werte beider xml dateien vergleichen. @blackjack, hast du den code selber geschrieben oder??? Also, wenn du es selber geschrieben hast, dann weißt du ja was für ein problem ich habe. Es ist genau das selbe problem wie mit den attributen. Nur diesesmal habe ich keine dictionary, sondern stringtexte, wenn ich print element1.tag ausgebe.
Wenn es für dictionaries geht, dann müsste es doch auch für stringtexte gehen oder???

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 23:18
von Sirius3
@machupicchu: was bedeutet bei Deinen Daten "gleich"? Zum Beispiel die <Item>s: Ist die Reihenfolge relevant? Oder sollen sie anhand der PartNumber indiziert werden? Können dann mehrere <Item>s die gleiche PartNumber haben? Wie soll man damit umgehen. Im einen Fall stimmt der Inhalt aber die PartNumber nicht, im anderen Fall sind die PartNumbers gleich aber der Inhalt völlig verschieden, welche Paarung ist nun gleicher? Für <Address> gibt es keine PartNumber, wie soll da die Sortierung/Vergleich stattfinden?

Re: Dict sortieren!

Verfasst: Donnerstag 13. Juni 2013, 23:33
von machupicchu
Also, in der xml datei wird lediglich nur ein element gelöscht. Guck dir nochmal meine erste xml an, da steht in der 9 zeile "hier gelöscht". Da habe ich ein elemente gelöscht, dass aber in der zweiten xml existiert. Wenn man jetzt den tag für die erste xml ausgibt und diese mit der zweiten xml gegenüberstellt, dann stimmt die reihenfolge nicht mehr. Das problem hatte ich auch mit den attributen gehabt und jetzt funktionierts. Dies möchte ich auch mit den elementen machen.

Attribute DICTIONARY

Code: Alles auswählen

D = {'Tel': '01634498766', 'Addresse': 'Berlinerallee 19', 'User': 'Max', 'ID': '111'}

Elemente Ausgabe Konsole:

Code: Alles auswählen

print element1.tag, element2.tag
PurchaseOrder PurchaseOrder
Address Address
Name Name
Street Street
City City
State State
Zip Zip
Address Country
Name Address
Street Name
City Street
State City
Zip State
Country Zip
DeliveryNotes Country
Items DeliveryNotes
Item Items
ProductName Item
Quantity ProductName
USPrice Quantity
Comment USPrice

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 06:23
von Sirius3
nochmals, Tags sind anders als Attribute. Tags haben eine Reihenfolge, können mehrfach auftreten, haben eine Unterstruktur. Du kannst natürlich die ganze Struktur vergessen und die Tags in ein Dictionary packen, bleiben aber die Fragen von oben, vor allem bekommst Du Probleme mit Mehrfacheinträgen.

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 08:22
von machupicchu
@sirius, Kannst du mir vlt verraten, wie ich die tags in ein dictionary packen kann?
Oder eine Idee wie ich das ganze umsetzen kann?

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 12:15
von BlackJack
@machupicchu: Kann es sein, dass Du eigentlich so eine Bibliothek wie http://www.logilab.org/project/xmldiff suchst‽

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 13:21
von machupicchu
Weiß ich jetzt nicht, ob ich sowas suche. Gibt es da eine dokumentation oder ein beispiel dazu?

Also, wenn ich wüsste, wie man zwei stringlisten so sortiert, dass leere zeilen mitberücksichtigt werden. Dann wäre ich schon mal ein schritt weiter.
Hatte jetzt noch die stringlisten in ein dictionary umgewandelt und bin noch dabei diese wie gewünscht auszugeben und zu vergleichen.

Code: Alles auswählen

str1 = "one, two, three, four, five, six, seven, eight, nine"
str2 = "one, two, three, five, six, seven, eight, nine"
list1 = str1.split(", ")
list2 = str2.split(", ")
listMerge = dict(zip(list1, list2))
print listMerge

Mit python mengen habe ich es nicht hinbekommen. Dachte jetzt vlt an einer linked list oder double linked list. Ein binary tree wäre da jetzt auch weniger sinnvoll, da sich die xml datei routiert, sobald man ein element oder attribut löscht.
Nun ja, was soll ich noch sagen. Mit attributen hat es zumindest geklappt.

Hatte auch mal die stringliste in dictionaries umgewandelt. Bin da aber auch nicht weiter gekommen.

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 14:02
von BlackJack
@machupicchu: Im Quelltextarchiv ist ein `doc/`-Unterordner und man hat halt den Quelltext. Ausserdem hat Logilab eine Mailingliste für die XML-Werkzeuge die sie geschrieben haben.

Um festzustellen ob in einer Sequenz etwas eingefügt, gelöscht, oder verändert/ausgetauscht wurde, kann man sich mit `difflib` aus der Standardbibliothek etwas schreiben.

Edit: Bevor Du verkettete Listen selber implementierst, solltest Du erst einmal schauen ob der `list`-Datentyp nicht ausreicht. Oder `collections.deque` falls auch vorne Elemente effizient hinzugefügt und/oder entfernt werden sollen. Was Du mit einem Binärbaum hier anfangen willst, ist mir nicht klar. Ein Element kann ja mehr als ein Kindelement haben, beziehungsweise hat das in den Beispielen ja auch.

Edit2: Eine wichtige Frage ist auch ob die Reihenfolge der Tags von dem XML-Format garantiert werden, denn falls nicht, müsstest Du ja auch erkennen können wenn zwar die gleichen Kindelemente in beiden Dokumenten vorkommen, aber in einer vertauschten Reihenfolge. *Da* hilft `difflib` nicht mehr weiter.

Re: Dict sortieren!

Verfasst: Freitag 14. Juni 2013, 21:13
von machupicchu
Ok danke erstmal!
Ich denke ich werde da jetzt nichts mehr machen. Komme da nicht weiter.
Die attribute mit den werten reichen erstmal aus denke ich!