Diktat in OrderedDict konvertieren


138

Ich habe einige Probleme mit der collections.OrderedDictKlasse. Ich verwende Python 2.7 auf Raspbian, der Debian-Distribution für Raspberry Pi. Ich versuche, zwei Wörterbücher zu drucken, um sie (nebeneinander) für ein Textabenteuer zu vergleichen. Die Reihenfolge ist wichtig, um genau zu vergleichen. Egal, was ich versuche, die Wörterbücher werden auf ihre übliche ungeordnete Weise gedruckt.

Folgendes bekomme ich, wenn ich es auf meinem RPi mache:

import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

Offensichtlich stimmt etwas nicht, weil es den Funktionsaufruf druckt und die Schlüssel und Wertgruppen in eine verschachtelte Liste setzt ...

Folgendes habe ich erhalten, indem ich auf meinem PC etwas Ähnliches ausgeführt habe:

import collections

Joe = {"Age": 28, "Race": "Latino", "Job": "Nurse"}
Bob = {"Age": 25, "Race": "White", "Job": "Mechanic", "Random": "stuff"}

#Just for clarity:
Joe = collections.OrderedDict(Joe)
Bob = collections.OrderedDict(Bob)

print Joe
# OrderedDict([('Age', 28), ('Race', 'Latino'), ('Job', 'Nurse')])
print Bob
# OrderedDict([('Age', 25), ('Race', 'White'), ('Job', 'Mechanic'), ('Random', 'stuff')])

Diesmal ist es in Ordnung, aber es sollte nicht die anderen Dinge drucken, oder? (Das Einfügen in die Liste und das Anzeigen des Funktionsaufrufs.)

Wo mache ich meinen Fehler? Es sollte nichts mit der pi-Version von Python zu tun haben, da es sich nur um die Linux-Version handelt.


2
Hinweis: OrderedDictist nach Einfügereihenfolge sortiert, nicht nach alphanumerischer Schlüsselreihenfolge.
el.pescado

Antworten:


214

Sie erstellen ein Wörterbuch zuerst , dann das Wörterbuch ein Passieren OrderedDict. Bei Python-Versionen <3.6 (*) ist die Reihenfolge zu diesem Zeitpunkt nicht mehr korrekt. dictist von Natur aus nicht bestellt.

Geben Sie stattdessen eine Folge von Tupeln ein:

ship = [("NAME", "Albatross"),
        ("HP", 50),
        ("BLASTERS", 13),
        ("THRUSTERS", 18),
        ("PRICE", 250)]
ship = collections.OrderedDict(ship)

Was Sie sehen, wenn Sie das drucken, OrderedDictist seine Darstellung , und es ist völlig korrekt. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])zeigt Ihnen nur in einer reproduzierbaren Darstellung, was der Inhalt des ist OrderedDict.


(*) : In der CPython 3.6-Implementierung wurde der dictTyp aktualisiert, um eine speichereffizientere interne Struktur zu verwenden, die den glücklichen Nebeneffekt hat, die Einfügereihenfolge beizubehalten, und im weiteren Sinne funktioniert der in der Frage gezeigte Code ohne Probleme. Ab Python 3.7 wurde die Python-Sprachspezifikation aktualisiert, sodass alle Python-Implementierungen diesem Verhalten folgen müssen. In dieser anderen Antwort von mir finden Sie Details und auch, warum Sie in OrderedDict()bestimmten Fällen immer noch eine verwenden möchten .


Ok, also wird OrderedDict das Wörterbuch für mich erstellen? Kann ich zum Drucken ohne die reproduzierbare Darstellung auch nur die Variable drucken, in der OrderedDict verwendet wird? dh: print ship ?? Danke :)
Pythonpiboy

3
Frage: Wie Sie beschrieben haben, erstellt OrderedDict eine geordnete "Liste". Besiegt das nicht den Zweck? Es wird nur eine Liste von Elementen erstellt, keine Wörterbücher mit Schlüsseln und Werten ...
Pythonpiboy

9
Der Typ verhält sich wie beides; eine Zuordnung, die Ordnung behält. Um eine Bestellung zu erstellen, müssen Sie die Artikel der Reihe nach angeben . Da ein Standard-Diktat (auf etwas anderem als PyPI oder Python 3.6+) dies nicht kann, geben Sie ihm stattdessen eine Liste von Tupeln. Sobald das erstellt ist,OrderedDict ist es ein Wörterbuch.
Martijn Pieters

4
Klingt so, als ob die Verwirrung von der Annahme herrührt, dass ein OrderedDict eine Bestellung "anwendet", anstatt nur eine Bestellung beizubehalten. Ich bin sicher davon ausgegangen, dass die Eingabe bei der Erstellung sortiert wird - oder dass die Funktion items () sortierte Elemente zurückgibt, unabhängig davon, wann sie eingefügt wurden. Stattdessen bleibt die von Ihnen angegebene Bestellung erhalten.
whiterook6

2
@ whiterook6: Es ist kein sortiertes Wörterbuch Nr. Es ist ein geordnetes Wörterbuch, ein Wörterbuch, das die Reihenfolge der Schlüssel-Wert-Paare aufzeichnet und es Ihnen ermöglicht, diese Paare neu zu ordnen. Vergleichen Sie dies mit Listen, bei denen es sich um geordnete Sequenzen handelt .
Martijn Pieters

36

Wenn Sie diesen Teil des Codes, in dem Ihr Diktat definiert wurde, nicht bearbeiten können, können Sie ihn jederzeit wie gewünscht bestellen:

from collections import OrderedDict

order_of_keys = ["key1", "key2", "key3", "key4", "key5"]
list_of_tuples = [(key, your_dict[key]) for key in order_of_keys]
your_dict = OrderedDict(list_of_tuples)

11

Die meiste Zeit entscheiden wir uns für OrderedDict, wenn wir eine benutzerdefinierte Bestellung benötigen, keine generische wie ASC usw.

Hier ist die vorgeschlagene Lösung:

import collections
ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship


new_dict = collections.OrderedDict()
new_dict["NAME"]=ship["NAME"]
new_dict["HP"]=ship["HP"]
new_dict["BLASTERS"]=ship["BLASTERS"]
new_dict["THRUSTERS"]=ship["THRUSTERS"]
new_dict["PRICE"]=ship["PRICE"]


print new_dict

Dies wird ausgegeben:

OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])
OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

Hinweis : Die neuen sortierten Wörterbücher behalten ihre Sortierreihenfolge bei, wenn Einträge gelöscht werden. Wenn jedoch neue Schlüssel hinzugefügt werden, werden die Schlüssel an das Ende angehängt und die Sortierung wird nicht beibehalten. ( Offizielles Dokument )


2

Verwenden Sie dict.items (); Es kann so einfach sein wie folgt:

ship = collections.OrderedDict(ship.items())
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.