Digamos que tengo el siguiente código:
import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'
¿Hay alguna manera de acceder a los elementos de forma numerada, como:
d(0) #foo's Output
d(1) #bar's Output
Digamos que tengo el siguiente código:
import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'
¿Hay alguna manera de acceder a los elementos de forma numerada, como:
d(0) #foo's Output
d(1) #bar's Output
Si OrderedDict()
es así, puede acceder fácilmente a los elementos indexando obteniendo las tuplas de pares (clave, valor) de la siguiente manera
>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')
Nota para Python 3.X
dict.items
devolvería un objeto de vista dict iterable en lugar de una lista. Necesitamos ajustar la llamada a una lista para hacer posible la indexación.
>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')
items
método devuelve un objeto de vista de diccionario interable en lugar de una lista, y no admite la división o indexación. Entonces primero deberías convertirlo en una lista. docs.python.org/3.3/library/stdtypes.html#dict-viewslist(d.items())
list(d.items())
utilizandonext(islice(d.items(), 1))
para obtener('bar', 'spam')
¿Tiene que usar un OrderedDict o desea específicamente un tipo de mapa que esté ordenado de alguna manera con indexación posicional rápida? Si es lo último, considere uno de los muchos tipos de dict ordenados de Python (que ordena los pares clave-valor en función del orden de clasificación de las claves). Algunas implementaciones también admiten indexación rápida. Por ejemplo, el proyecto sortedcontainers tiene un tipo SortedDict solo para este propósito.
fuente
SortedDict
con una función clave para evitar comparaciones. Al igual que:SortedDict(lambda key: 0, ...)
. Las claves estarán sin clasificar pero permanecerán en un orden estable y son indexables.Aquí hay un caso especial si desea la primera entrada (o cerca de ella) en un OrderedDict, sin crear una lista. (Esto se ha actualizado a Python 3):
(La primera vez que dices "siguiente ()", realmente significa "primero").
En mi prueba informal,
next(iter(d.items()))
con un pequeño OrderedDict es solo un poquito más rápido queitems()[0]
. Con un OrderedDict de 10,000 entradas,next(iter(d.items()))
fue aproximadamente 200 veces más rápido queitems()[0]
.PERO si guarda la lista de elementos () una vez y luego usa mucho la lista, podría ser más rápido. O si repetidamente {crea un iterador de ítems () y avanza hasta la posición que desea}, eso podría ser más lento.
fuente
OrderedDict
s no tienen uniteritems()
método, por lo que tendrá que hacer lo siguiente con el fin de obtener el primer punto:next(iter(d.items()))
.d.items()
no parece ser un iterador, por lo tanto, ¿por delante no ayudará? Todavía devolverá la lista completa :(odict_iterator
y me confirmaron en IRC #python que esto no hace una copia de la lista.Es dramáticamente más eficiente usar IndexedOrderedDict del
indexed
paquete.Siguiendo el comentario de Niklas, hice un punto de referencia en OrderedDict e IndexedOrderedDict con 1000 entradas.
IndexedOrderedDict es ~ 100 veces más rápido en elementos de indexación en una posición específica en este caso específico.
fuente
indexed.py
lugar deindexed
.Este wiki comunitario intenta recopilar respuestas existentes.
Python 2.7
En Python 2, las
keys()
,values()
yitems()
las funciones deOrderedDict
las listas de retorno. Usandovalues
como ejemplo, la forma más simple esPara colecciones grandes donde solo le importa un índice único, puede evitar crear la lista completa utilizando las versiones del generador
iterkeys
,itervalues
yiteritems
:El paquete indexed.py proporciona
IndexedOrderedDict
, que está diseñado para este caso de uso y será la opción más rápida.El uso de itervalues puede ser considerablemente más rápido para diccionarios grandes con acceso aleatorio:
Python 3.6
Python 3 tiene las mismas dos opciones básicas (lista vs generador), pero los métodos dict devuelven generadores por defecto.
Método de la lista:
Método generador:
Los diccionarios de Python 3 son un orden de magnitud más rápido que python 2 y tienen aceleraciones similares para usar generadores.
fuente
Es una nueva era y con los diccionarios Python 3.6.1 ahora conservan su orden. Estas semánticas no son explícitas porque eso requeriría la aprobación de BDFL. Pero Raymond Hettinger es la segunda mejor opción (y más divertida) y argumenta que los diccionarios se ordenarán por mucho tiempo.
Así que ahora es fácil crear secciones de un diccionario:
Nota: La preservación del orden de inserción dictonario ahora es oficial en Python 3.7 .
fuente
para OrderedDict () puede acceder a los elementos indexando obteniendo las tuplas de pares (clave, valor) de la siguiente manera o usando '.values ()'
fuente