sortiertes Dictionary

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

sortiertes Dictionary (last edited 2011-07-10 19:12:11 by ReimarBauer)