¿Cómo recuperar los elementos de un diccionario en el orden en que está inserta?

StackOverflow https://stackoverflow.com/questions/60848

  •  09-06-2019
  •  | 
  •  

Pregunta

Es posible recuperar los elementos de un diccionario de Python en el orden en que se inserta?

¿Fue útil?

Solución

El estándar de Python dict hace esto por defecto si usted está usando CPython 3.6+ (o Python 3.7+ para cualquier otra aplicación de Python).

En anteriores versiones de Python puede utilizar collections.OrderedDict.

Otros consejos

Las otras respuestas son correctas;no es posible, pero usted podría escribir esto por sí mismo.Sin embargo, en caso de que usted está seguro de cómo realmente implementar algo como esto, he aquí un completo y práctico de aplicación que las subclases de dict que yo he escrito y probado.(Tenga en cuenta que el orden de los valores que se pasan al constructor no está definido, pero llegará antes de que los valores que se pasan más tarde, y siempre se puede simplemente no permitir que ordenó dicts ser inicializado con los valores.)

class ordered_dict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self._order = self.keys()

    def __setitem__(self, key, value):
        dict.__setitem__(self, key, value)
        if key in self._order:
            self._order.remove(key)
        self._order.append(key)

    def __delitem__(self, key):
        dict.__delitem__(self, key)
        self._order.remove(key)

    def order(self):
        return self._order[:]

    def ordered_items(self):
        return [(key,self[key]) for key in self._order]


od = ordered_dict()
od["hello"] = "world"
od["goodbye"] = "cruel world"
print od.order()            # prints ['hello', 'goodbye']

del od["hello"]
od["monty"] = "python"
print od.order()            # prints ['goodbye', 'monty']

od["hello"] = "kitty"
print od.order()            # prints ['goodbye', 'monty', 'hello']

print od.ordered_items()
# prints [('goodbye','cruel world'), ('monty','python'), ('hello','kitty')]

Uso OrderedDict(), disponible desde la versión 2.7

Sólo una cuestión de curiosidad:

from collections import OrderedDict
a = {}
b = OrderedDict()
c = OredredDict()

a['key1'] = 'value1'
a['key2'] = 'value2'

b['key1'] = 'value1'
b['key2'] = 'value2'

c['key2'] = 'value2'
c['key1'] = 'value1'

print a == b #True
print a == c #True
print b == c #False

O, simplemente, hacer la clave de una tupla con el tiempo.ahora() como el primer campo en la tupla.

A continuación, puede recuperar las claves con dictname.las teclas(), sort, y voila!

Gerry

Como de Python 3.7, el estándar dict conserva el orden de inserción.A partir de la docs:

Cambiado en la versión 3.7:Diccionario de la orden está garantizado para ser orden de inserción.Este comportamiento se detalle en la implementación de CPython de 3.6.

Así, usted debería ser capaz de recorrer el diccionario normalmente o uso popitem().

Usted no puede hacer esto con la base dict clase-es ordenado por el hash.Usted puede construir su propio diccionario que es realmente una lista de claves,los pares de valores o somesuch, que iba a ser ordenado.

He usado StableDict antes con buen éxito.

http://pypi.python.org/pypi/StableDict/0.2

O el uso de cualquiera de las implementaciones para la PEP-372 se describe aquí, como el odict módulo a partir de la pythonutils.

He utilizado con éxito la pocoo.org la aplicación, es tan fácil como la sustitución de su

my_dict={}
my_dict["foo"]="bar"

con

my_dict=odict.odict()
my_dict["foo"]="bar"

y sólo requieren este archivo

No es posible a menos que almacenar las claves en una lista separada para hacer referencia más adelante.

Lo que puedes hacer es insertar los valores con una tecla que representa el orden ingresado y, a continuación, llamar a sorted() en los elementos.

>>> obj = {}
>>> obj[1] = 'Bob'
>>> obj[2] = 'Sally'
>>> obj[3] = 'Joe'
>>> for k, v in sorted(obj.items()):
...     print v
... 
Bob
Sally
Joe
>>> 

si usted no necesita el diccionario de la funcionalidad, y sólo necesita devolver tuplas en el orden que usted ha insertado ellos, no una cola de trabajo mejor?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top