2010-02-24 3 views
20

я должен решить это упражнение:Python: Расширение «Словарь» класс

словари языка Python не сохранять порядок вставляемых данных и не хранить данные, упорядоченных по ключу. Напишите расширение для класса dict, экземпляры которого будут хранить данные, отсортированные по их значению ключа. Обратите внимание, что порядок должен сохраняться также при добавлении новых элементов.

Как продлить dict? Нужно ли иметь доступ к исходному коду для типа dict?

+2

hmmm ... домашнее задание? – jldupont

ответ

27

Вы можете подкласса dict или UserDict, так как van уже говорил о UserDict, давайте посмотрим на dict.

Тип help(dict) в интерпретатор, и вы видите большой список методов. Вам нужно будет переопределить все методы, которые изменяют dict, а также методы, которые выполняют итерацию по dict.

Метода, которые модифицируют Dict включает __delitem__, __setitem__, clear и т.д.

Методы, которые итерируют Dict включает __iter__, keys, values, items и т.д.

Это поможет вам начать

>>> 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? Я начал менять 'self.itemlist.append (key)' с 'set (self.itemlist) .add (key)', чтобы заставить его работать, но порядок больше не сохраняется – z3d0

+0

@ z3d0r, В Python3, '.keys () 'больше не возвращает список, поэтому вам нужно будет использовать' self.itemlist = list (super (odict, self) .keys()) 'в методе' __init__'. –

+0

спасибо, я также заметил, что методы 'values ​​()' и 'itervalues ​​()' больше не существуют и что 'keys()' - это набор, а не список, поэтому 'def keys (self): return set (self.itemlist) 'будет правильным? Все еще работая над этим, потому что заказ еще не сохранен – z3d0

9

Реализация dict не поможет вам с задачей. То, что вы хотите, - это класс, имеющий тот же интерфейс, что и dict, но другая реализация. That will require to implement methods like __getitem__, __setitem__, etc. Если вы Google для «orderdict», вы найдете много примеров.

+2

Прочтите информацию collections.ABC о расширении 'Mapping' для реализации упорядоченного словаря.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, источник которого вы можете найти в /lib/UserDict.py вашего дистрибутива python.

+0

@ user280560: Если вы это сделаете, убедитесь, что вы сказали своему инструктору, откуда вы получили код, так как вы его не пишете, а downlaoded. –

+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, чтобы получить некоторые идеи, но не копировать/вставить, ваш учитель не будет видеть его любезно.