ordereddict dict python python-3.x ordereddictionary

ordereddict python 3



Ăšltimo elemento en OrderedDict (3)

Usar next(reversed(od)) es una forma perfecta de acceder al elemento agregado más recientemente. La clase OrderedDict usa una lista doblemente vinculada para los ítems del diccionario e implementa __reversed__() , por lo que esta implementación le da O (1) acceso al elemento deseado. Si vale la pena subclase OrderedDict() para esta operación simple puede ser cuestionada, pero no hay nada realmente malo con este enfoque.

Tengo od del tipo OrderedDict . Quiero acceder a su par agregado más recientemente (clave, valor). od.popitem(last = True) lo haría, pero también eliminaría el par de od que no quiero.

¿Cuál es una buena manera de hacer eso? Puedo / debería hacer esto:

class MyOrderedDict(OrderedDict): def last(self): return next(reversed(self))


Su idea está bien, sin embargo, el iterador predeterminado solo está sobre las teclas, por lo que su ejemplo solo devolverá la última clave. Lo que realmente quieres es:

class MyOrderedDict(OrderedDict): def last(self): return list(self.items())[-1]

Esto proporciona los pares (key, value) , no solo las claves, como usted quería.

Tenga en cuenta que en versiones anteriores a 3.x de Python, OrderedDict.items() devuelve una lista, por lo que no necesita la llamada list() , pero las versiones posteriores devuelven un objeto de vista de diccionario , por lo que lo hará.

Editar: Como se señaló en los comentarios, la operación más rápida es hacer:

class MyOrderedDict(OrderedDict): def last(self): key = next(reversed(self)) return (key, self[key])

Aunque debo admitir que encuentro esto más feo en el código (nunca me gustó obtener la clave y luego hacer x[key] para obtener el valor por separado, prefiero obtener la tupla (key, value) ), dependiendo de la importancia de la velocidad y sus preferencias, es posible que desee elegir la opción anterior.


Un poco de magia de Timeit puede ayudar aquí ...

from collections import OrderedDict class MyOrderedDict1(OrderedDict): def last(self): k=next(reversed(self)) return (k,self[k]) class MyOrderedDict2(OrderedDict): def last(self): out=self.popitem() self[out[0]]=out[1] return out class MyOrderedDict3(OrderedDict): def last(self): k=(list(self.keys()))[-1] return (k,self[k]) if __name__ == "__main__": from timeit import Timer N=100 d1=MyOrderedDict1() for i in range(N): d1[i]=i print ("d1",d1.last()) d2=MyOrderedDict2() for i in range(N): d2[i]=i print ("d2",d2.last()) d3=MyOrderedDict3() for i in range(N): d3[i]=i print("d3",d3.last()) t=Timer("d1.last()",''from __main__ import d1'') print ("OrderedDict1",t.timeit()) t=Timer("d2.last()",''from __main__ import d2'') print ("OrderedDict2",t.timeit()) t=Timer("d3.last()",''from __main__ import d3'') print ("OrderedDict3",t.timeit())

resultados en:

d1 (99, 99) d2 (99, 99) d3 (99, 99) OrderedDict1 1.159217119216919 OrderedDict2 3.3667118549346924 OrderedDict3 24.030261993408203

(Probado en python3.2, Ubuntu Linux).

Como señala @SvenMarnach, el método que describió es bastante eficiente en comparación con las otras dos formas en que podría cocinar.