python-collections — Tipo de datos de contenedor (diccionario ordenado)
Código fuente: Lib/collections/ init.py Este módulo implementa contenedores
específicos de destino para proporcionar una alternativa a los contenedores integrados estándar de Python dict , list , set y tuple .
nombre | efecto |
---|---|
tupla nombrada() | Función de fábrica para crear subclases de tupla con nombre |
por lo tanto | Un contenedor similar a una lista (list), que realiza una rápida adición (adjuntar) y una ventana emergente (pop) en ambos extremos |
CadenaMapa | Una clase de contenedor similar a un diccionario (dict), que recopila múltiples asignaciones en una vista |
Encimera | Una subclase de Dictionary que proporciona funcionalidad de conteo para objetos hashable |
dictado ordenado | Una subclase de Dictionary que conserva el orden en que se agregaron |
predeterminadodict | Una subclase de diccionario que proporciona una función de fábrica para proporcionar un valor predeterminado para consultas de diccionario |
UserDict | Encapsula objetos de diccionario, lo que simplifica la creación de subclases de diccionario |
Lista de usuarios | Encapsula objetos de lista, lo que simplifica la creación de subclases de lista |
Cadena de usuario | Encapsula objetos de cadena, lo que simplifica la subclasificación de cadenas |
colecciones de clases.OrderedDict([elementos])
Devuelve una instancia de una subclase dict con métodos específicos para reorganizar el orden lexicográfico.
3.1 nuevas características.
El método popitem() del diccionario ordenado popitem(last=True)
elimina y devuelve un par clave-valor (clave, valor). Si el último valor es verdadero, los pares clave-valor se devuelven en orden LIFO; de lo contrario, los pares clave-valor se devuelven en orden FIFO.
move_to_end(key, last=True)
mueve una clave existente a cualquier extremo del diccionario ordenado. Mueve la entrada a la derecha si el último es verdadero (el valor predeterminado) o al principio si el último es falso. Genera KeyError si la clave no existe:
>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d)
'acdeb'
>>> d.move_to_end('b', last=False)
>>> ''.join(d)
'bacde'
3.2 nuevas características.
En comparación con el método de mapeo habitual, el diccionario ordenado también brinda soporte para la iteración inversa a través de reversed().
Las pruebas de igualdad entre OrderedDicts son sensibles al orden, implementadas como list(od1.items())==list(od2.items()) . Las pruebas de igualdad para objetos OrderedDict y otras asignaciones son pruebas de diccionario sensibles al orden. Esto permite reemplazar OrderedDict donde se puede usar cualquier diccionario.
Modificado en la versión 3.5: las vistas de elemento, clave y valor de OrderedDict ahora admiten la iteración inversa, a través de reversed().
Cambiado en la versión 3.6: PEP 468 favorece la preservación del orden de los argumentos de palabras clave pasados al constructor OrderedDict y su método update().
Cambiado en la versión 3.9: Se agregaron operadores de combinación (|) y actualización (|=), como se explica en PEP 584
Ejemplo y uso de OrderedDict
La clave de OrderedDict se ordenará en el orden de inserción, no la clave en sí
import collections
print "Regular dictionary"
d={
}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
print k,v
print "\nOrder dictionary"
d1 = collections.OrderedDict()
d1['a'] = 'A'
d1['b'] = 'B'
d1['c'] = 'C'
d1['1'] = '1'
d1['2'] = '2'
for k,v in d1.items():
print k,v
输出:
Regular dictionary
a A
c C
b B
Order dictionary
a A
b B
c C
1 1
2 2
Se puede ver que varios elementos como ABC también se guardan, pero el uso de OrderedDict ordenará según el orden en que se colocan los elementos. Entonces los valores de salida están ordenados.
Los objetos del diccionario del objeto OrderedDict, si el orden es diferente, Python los tratará como dos objetos diferentes, vea el ejemplo:
print 'Regular dictionary:'
d2={
}
d2['a']='A'
d2['b']='B'
d2['c']='C'
d3={
}
d3['c']='C'
d3['a']='A'
d3['b']='B'
print d2 == d3
print '\nOrderedDict:'
d4=collections.OrderedDict()
d4['a']='A'
d4['b']='B'
d4['c']='C'
d5=collections.OrderedDict()
d5['c']='C'
d5['a']='A'
d5['b']='B'
print d1==d2
输出:
Regular dictionary:
True
OrderedDict:
False
Mira algunos ejemplos más:
dd = {
'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
#按key排序
kd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[0]))
print kd
#按照value排序
vd = collections.OrderedDict(sorted(dd.items(),key=lambda t:t[1]))
print vd
#输出
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
Esta parte de la introducción del ejemplo se transfiere de tooltime
Es sencillo crear variantes de diccionario ordenadas que recuerden el orden en que se insertaron las claves por última vez. Si una nueva entrada sobrescribe una entrada existente, la posición de inserción original se cambia y se mueve al final:
class LastUpdatedOrderedDict(OrderedDict):
'Store items in the order the keys were last added'
def __setitem__(self, key, value):
super().__setitem__(key, value)
self.move_to_end(key)
Un OrderedDict también es útil para implementar variantes de functools.lru_cache():
from time import time
class TimeBoundedLRU:
"LRU Cache that invalidates and refreshes old entries."
def __init__(self, func, maxsize=128, maxage=30):
self.cache = OrderedDict() # { args : (timestamp, result)}
self.func = func
self.maxsize = maxsize
self.maxage = maxage
def __call__(self, *args):
if args in self.cache:
self.cache.move_to_end(args)
timestamp, result = self.cache[args]
if time() - timestamp <= self.maxage:
return result
result = self.func(*args)
self.cache[args] = time(), result
if len(self.cache) > self.maxsize:
self.cache.popitem(0)
return result
class MultiHitLRUCache:
""" LRU cache that defers caching a result until
it has been requested multiple times.
To avoid flushing the LRU cache with one-time requests,
we don't cache until a request has been made more than once.
"""
def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):
self.requests = OrderedDict() # { uncached_key : request_count }
self.cache = OrderedDict() # { cached_key : function_result }
self.func = func
self.maxrequests = maxrequests # max number of uncached requests
self.maxsize = maxsize # max number of stored return values
self.cache_after = cache_after
def __call__(self, *args):
if args in self.cache:
self.cache.move_to_end(args)
return self.cache[args]
result = self.func(*args)
self.requests[args] = self.requests.get(args, 0) + 1
if self.requests[args] <= self.cache_after:
self.requests.move_to_end(args)
if len(self.requests) > self.maxrequests:
self.requests.popitem(0)
else:
self.requests.pop(args, None)
self.cache[args] = result
if len(self.cache) > self.maxsize:
self.cache.popitem(0)
return result