In PHP existiert ein assoziatives Array, welches ähnlich dem Python-Dictionary arbeitet. Allerdings werden in Python die Reihenfolge der Einträge nicht festgehalten. Mit anderen Worten die Einträge werden "durcheinander" gespeichert.
Dieses "durcheinander" beim Speichern ist darauf zurückzuführen, dass Python die Daten so einordnet, dass man diese möglichst schnell abfragen und manipulieren kann.
Normalerweise braucht man nicht wirklich die Reihenfolge, weil ein Dict eigentlich dazu da ist, gezielt die Values passend zu einem Key nachzuschlagen. Somit ist der Wunsch nach einem sortierten Dict meist darauf zurückzuführen, dass die gewählte Datenstruktur nicht die optimale ist.
Dennoch kann man sich eine Lösung dafür bauen. Das Prinzip ist einfach. Es wird einfach neben dem Dict eine Liste (__keylist) geführt, in der die Position festgehalten werden:
1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 """
4 Modul: Lict
5 Description: Mix of list and dict
6 Version: 0.1.1
7 Copyright: 2004 by Fritz Cizmarov fritz@sol.at
8 Created: 16. Nov. 2004
9 Last modified: 20. Nov. 2004
10 License: free
11 Requirements: Python2.3
12 Exports: Classes and Functions to export
13 http://www.python-forum.de/viewtopic.php?t=2250
14 """
15
16
17 class Index(int):
18 """ Helperclass for access Lict by Index """
19 __slots__ = []
20
21 class Lict(dict):
22
23 __slots__ = ["__keylist"]
24
25 def __init__(self, *args, **kw):
26 super(Lict, self).__init__(*args, **kw)
27 self.__keylist = []
28 if len(args) == 1 and isinstance(args[0], (tuple, list)):
29 for key, value in args[0]:
30 self.__keylist.append(key)
31 for key in kw:
32 self.__keylist.append(key)
33
34 def __getitem__(self, key):
35 if type(key) is Index:
36 key = self.__keylist[key]
37 return super(Lict, self).__getitem__(key)
38
39 def __setitem__(self, key, value):
40 """ sets item, if item not exists append it """
41 if type(key) is Index:
42 key = self.__keylist[key]
43 elif key not in self.__keylist:
44 self.__keylist.append(key)
45 super(Lict, self).__setitem__(key, value)
46
47 def __delitem__(self, key):
48 if type(key) is Index:
49 key = self.__keylist[key]
50 super(Lict, self).__delitem__(key)
51 del self.__keylist[ self.__keylist.index(key) ]
52
53 def insert(self, index, key, value):
54 self.__keylist.insert(index, key)
55 super(Lict, self).__setitem__(key, value)
56
57 def __str__(self):
58 return "{" + ", ".join("%r: %r" % (k, v) for k, v in self.iteritems()) + "}"
59
60 def __repr__(self):
61 return "Lict(%r)" % list(self.iteritems())
62
63 def __iter__(self):
64 return iter(self.__keylist)
65
66 def iteritems(self):
67 for key in self.__keylist:
68 yield key, self[key]
69
70 iterkeys = __iter__
71
72 def itervalues(self):
73 for key in self.__keylist:
74 yield self[key]
75
76 def update(self, E):
77 if not isinstance(E, Lict):
78 raise TypeError("E is not from type Lict!")
79 for key in E:
80 self[key] = E[key]
81
82 def pop(self, key=None):
83 if key is None:
84 key = self.__keylist[-1]
85 elif type(key) is Index:
86 key = self.__keylist[key]
87 self.keylist.remove(key)
88 return super(Lict, self).pop(key)
89
90 def reverse(self):
91 self.__keylist.reverse()
92
93 def sort(self):
94 self.__keylist.sort()
95
96
97 if __name__=="__main__":
98 print "->",__file__,"<- SelbstTest\n"
99
100 def LictAusgeben():
101 print "="*40
102 for k,v in MyLict.iteritems():
103 print k,"-",v
104 print "="*40
105
106 MyLict = Lict()
107
108 MyLict["Key1"]="Wert1"
109 MyLict["Key2"]="Wert2"
110 MyLict["Key3"]="Wert3"
111
112 LictAusgeben()
113
114 MyLict["Key2"]="Wert2XX"
115
116 MyLict["Key4"]="Wert4"
117 MyLict["Key5"]="Wert5"
118
119 LictAusgeben()
120
121 del( MyLict["Key2"] )
122
123 LictAusgeben()
124
125 MyLict.insert(2, "Key2", "Wert2NEU")
126
127 LictAusgeben()
Alternativ gibt es einen Eintrag im Cookbook
Kommentar
Die hier vorgestellte Klasse stellt kein sortiertes Dictionary dar, sondern eins, das die Reihenfolge der der Einfügung der Keys erhält. -- ChristopherArndt 2007-11-20 00:53:47
In ner aktuellen Python Version kann man nun auch OrderedDict verwenden. OrderedDict | dict subclass that remembers the order entries -- ReimarBauer 2011-07-10 19:12:10