2010-02-24 65 views
20
的“字典”类

我必须解决这个练习:的Python:扩展

Python的词典不会保留插入数据的顺序,也没有存储由关键排序的数据。为dict类写一个扩展,其实例将保持数据按键值排序。请注意,添加新元素后,顺序也必须保留。

如何扩展dict?我需要访问dict类型的源代码吗?

+2

嗯......功课? – jldupont

回答

27

您可以继承dictUserDict,因为van已经提到过UserDict,请看dict

help(dict)键入到解释器中,您会看到一大串方法。您需要重写所有修改字典的方法以及迭代字典的方法。

中的方法修改字典包括__delitem____setitem__clear

中的方法遍历字典包括__iter__keysvaluesitems

这应该让你开始

>>> class odict(dict): 
...  def __init__(self, *args, **kw): 
...   super(odict,self).__init__(*args, **kw) 
...   self.itemlist = super(odict,self).keys() 
...  def __setitem__(self, key, value): 
...   # TODO: what should happen to the order if 
...   #  the key is already in the dict  
...   self.itemlist.append(key) 
...   super(odict,self).__setitem__(key, value) 
...  def __iter__(self): 
...   return iter(self.itemlist) 
...  def keys(self): 
...   return self.itemlist 
...  def values(self): 
...   return [self[key] for key in self] 
...  def itervalues(self): 
...   return (self[key] for key in self) 
... 
>>> od = odict(a=1,b=2) 
>>> print od 
{'a': 1, 'b': 2} 
>>> od['d']=4 
>>> od['c']=3 
>>> print od # look at the `__str__` and `__repr__` methods 
{'a': 1, 'c': 3, 'b': 2, 'd': 4} 
>>> print od.keys() 
['a', 'b', 'd', 'c'] 
>>> print od.values() 
[1, 2, 4, 3] 
+0

python 3的工作示例的任何机会?我开始用'set(self.itemlist).add(key)'改变'self.itemlist.append(key)'使它工作,但是顺序不再被保存 – z3d0

+0

@ z3d0r,在Python3中''keys )'不再返回一个列表,所以你需要在'__init__'方法中使用'self.itemlist = list(super(odict,self).keys())'。 –

+0

谢谢,我也注意到'values()'和'itervalues()'方法不再存在,而'keys()'是一个集合而不是一个列表,所以'def keys(self):返回集(self.itemlist)'是正确的?仍在继续工作,因为订单还没有保留 – z3d0

9

dict的执行不会帮你完成任务。你想要的是一个类与dict具有相同的接口,但不同的实现。 That will require to implement methods like __getitem__, __setitem__, etc.如果你是Google的“ordereddict”,你会发现很多例子。

+2

阅读有关扩展“Mapping”以实现有序字典的collections.ABC信息。http://docs.python.org/library/collections.html#abcs-abstract-base-classes。 –

5

如果您使用python 2.7+,则请参阅collections.OrderedDict
否则,backport(复制源代码)或参见Recipe 576693: Ordered Dictionary for Py2.4 (Python)

但如果你真的需要延长dict,然后用UserDict,来源,你可以在你的Python发行的/lib/UserDict.py找到启动。

+0

@ user280560:如果你这样做,确保你告诉你的导师你从哪里得到了代码,因为你没有写它,但下了它。 –

+0

@ S.Lott:我想他不允许复制粘贴,并且他们使用2.5/2.6。 – voyager

+2

我不认为这个任务是为了实现'OrderedDict',因为它保留了_insertion_的顺序而不是维护排序的键顺序。 –

5

好消息:问题并不难解决。

为了闲逛,看到一个class的内脏可以使用

>>> dir(dict) 
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 

help(dict),其中有一个非常完整的交互文档,当然你也有机会获得更完整的online documentation

一旦你掌握了dict在幕后做什么,你应该了解inheritance in Python

如果您遇到访问this site得到一些想法,但不要复制/粘贴,你的老师不会看到它亲切。