Como han mencionado otros, en Python los diccionarios están inherentemente desordenados. Sin embargo, en cualquier momento dado, se puede obtener una lista de sus claves actuales o pares clave y de valor utilizando sus métodos keys()
o items()
.
Un posible problema con el uso de estas listas es que no solo sus contenidos, sino también el orden en el que se devuelve variarán si el diccionario ha sido modificado (o mutado) desde la última vez que se usaron. Esto significa que generalmente no puede almacenar y reutilizar la lista a menos que la actualice cada vez que se cambia el diccionario, en caso de que la necesite.
Para hacer este enfoque más manejable, puede combinar un diccionario y la lista auxiliar en una nueva clase derivada que se encarga de la sincronización entre los dos y también proporciona un método get_range()
que hace uso de los contenidos actuales de la lista. A continuación se muestra un código de muestra que muestra cómo se podría hacer esto. Está basado en ideas que obtuve del código en this ActiveState Python Recipe.
class dict_with_get_range(dict):
def __init__(self, *args, **kwrds):
dict.__init__(self, *args, **kwrds)
self._list_ok = False
def _rebuild_list(self):
self._list = []
for k,v in self.iteritems():
self._list.append((k,v))
self._list_ok = True
def get_range(self, begin, end):
if not self._list_ok:
self._rebuild_list()
return dict(self._list[i] for i in range(begin,end+1))
def _wrapMutatorMethod(methodname):
_method = getattr(dict, methodname)
def wrapper(self, *args, **kwrds):
# Reset 'list OK' flag, then delegate to the real mutator method
self._list_ok = False
return _method(self, *args, **kwrds)
setattr(dict_with_get_range, methodname, wrapper)
for methodname in 'delitem setitem'.split():
_wrapMutatorMethod('__%s__' % methodname)
for methodname in 'clear update setdefault pop popitem'.split():
_wrapMutatorMethod(methodname)
del _wrapMutatorMethod # no longer needed
dct = dict_with_get_range({"a":"b", "c":"d", "e":"f"})
print dct.get_range(0, 1)
# {'a': 'b', 'c': 'd'}
del dct["c"]
print dct.get_range(0, 1)
# {'a': 'b', 'e': 'f'}
La idea básica consiste en derivar una nueva clase de dict
que también tiene una lista de contenido interno para su uso con el nuevo método get_range()
que establece que los objetos del diccionario regulares no lo hacen. Para minimizar la necesidad de actualizar (o incluso crear) esta lista interna, también tiene un indicador que indica si la lista está actualizada o no, y solo la revisa y reconstruye la lista cuando sea necesario.
Para mantener el indicador, cada método de diccionario heredado que potencialmente cambie (o muta) los contenidos del diccionario está "envuelto" con la función auxiliar, restablece el indicador y luego encadena al método normal del diccionario para realizar la operación. Instalarlos en la clase es simplemente una cuestión de poner los nombres de los métodos en una de dos listas y luego pasarlos uno por uno a una utilidad auxiliar inmediatamente después de la creación de la clase.
por __indexes__ te refieres a claves ??? – mouad
@singularity: Al mirar la pregunta pasada de OP http://stackoverflow.com/questions/4181367/python-possible-to-filter-dict, debería tener razón. – kennytm
NO, no por clave, justo después de ordenar (o no ordenar nada), quiero que las primeras/últimas/partes medias del dict ... –