2010-02-24 15 views
20

tengo que resolver este ejercicio:Python: Ampliación de la clase 'dict'

diccionarios de Python no preservan el orden de los datos insertados ni almacenar los datos ordenados por la clave. Escriba una extensión para la clase dict cuyas instancias mantendrán los datos ordenados por su valor clave. Tenga en cuenta que el orden debe conservarse también cuando se agregan nuevos elementos.

¿Cómo extiendo dict? ¿Debo tener acceso al código fuente para el tipo dict?

+2

hmmm ... ¿deberes? – jldupont

Respuesta

27

Puede la subclase dict o UserDict, ya que la camioneta ya ha hablado de UserDict, veamos dict.

Escriba help(dict) en un intérprete y verá una gran cantidad de métodos. Tendrá que anular todos los métodos que modifican el dict y los métodos que iteran sobre el dict.

métodos que modifican el dict incluyen __delitem__, __setitem__, etc. clear

Los métodos que iteran la dict incluir __iter__, keys, values, etc. items

Esto debería empezar

>>> 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

alguna posibilidad de un ejemplo de trabajo con python 3? Empecé a cambiar 'self.itemlist.append (key)' con 'set (self.itemlist) .add (key)' para que funcione, pero el orden ya no se conserva – z3d0

+0

@ z3d0r, en Python3, '.keys () 'ya no devuelve una lista, por lo que necesitaría usar' self.itemlist = list (super (odict, self) .keys()) 'en el método' __init__'. –

+0

gracias, también noté que los métodos 'values ​​()' y 'itervalues ​​()' ya no existen, y que 'keys()' es un conjunto y no una lista, por lo que 'def keys (self): return set (self.itemlist) '¿ser correcto? Aún trabajando en ello porque la orden aún no se ha conservado – z3d0

9

La implementación de dict no lo ayudará con la tarea. Lo que quiere es una clase que tenga la misma interfaz que dict, pero una implementación diferente. That will require to implement methods like __getitem__, __setitem__, etc. Si busca "orderdict" en Google, encontrará muchos ejemplos.

+2

Lea la información collections.ABC sobre la ampliación de 'Mapping' para implementar un diccionario ordenado.http://docs.python.org/library/collections.html#abcs-abstract-base-classes. –

5

Si usa Python 2.7+, entonces vea collections.OrderedDict.
De lo contrario, backport (copie la fuente) o vea Recipe 576693: Ordered Dictionary for Py2.4 (Python).

Pero si realmente necesita extender el dict, entonces comience con UserDict, fuente para la que puede encontrar en /lib/UserDict.py de su distribución python.

+0

@ user280560: Si hace esto, asegúrese de decirle a su instructor de dónde obtuvo el código, ya que no lo escribió, sino que lo bajó. –

+0

@ S.Lott: Imagino que no tiene permiso para copiar y pegar, y que están usando 2.5/2.6. – voyager

+2

No creo que la tarea fuera implementar 'OrderedDict' tampoco, ya que preserva el orden _insertion_ en lugar de mantener el orden de las claves ordenadas. –

5

Buenas noticias: el problema no es difícil en absoluto.

Con el fin de curiosear y ver las entrañas de un class puede utilizar

>>> 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'] 

y help(dict), que tiene una documentación interactiva muy completa, pero por supuesto también tiene acceso a la más completa online documentation .

Una vez que tenga una idea de lo que dict hace detrás de las escenas, debe aprender acerca de inheritance in Python.

si se queda atascadothis site visita para obtener algunas ideas, pero no copiar/pegar, el maestro no lo verá amablemente.

Cuestiones relacionadas