Considere el siguiente diccionario, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
Quiero devolver la primera clave N: pares de valor de d (N <= 4 en este caso). ¿Cuál es el método más eficaz para hacer esto?
Considere el siguiente diccionario, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
Quiero devolver la primera clave N: pares de valor de d (N <= 4 en este caso). ¿Cuál es el método más eficaz para hacer esto?
Respuestas:
No existen las "primeras n" teclas porque a dictno recuerda qué teclas se insertaron primero.
Usted puede obtener cualquier pares de clave y valor n sin embargo:
n_items = take(n, d.iteritems())
Esto utiliza la implementación de takelas itertoolsrecetas :
from itertools import islice
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
Véalo funcionando en línea: ideone
Actualización para Python 3.6
n_items = take(n, d.items())
iteritemsdebería ser reemplazado por itemspara la gente en Python 3
take()parte de la base del código de Python en algún lugar? ¿O es simplemente la función que definió en su respuesta aquí? Preguntando como si fuera parte del código base, no puedo encontrarlo / importarlo. :)
Una forma muy eficaz de recuperar cualquier cosa es combinar las comprensiones de listas o diccionarios con la división. Si no necesita ordenar los elementos (solo quiere n pares aleatorios), puede usar una comprensión de diccionario como esta:
# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}
Generalmente, una comprensión como esta es siempre más rápida de ejecutar que el ciclo equivalente "para x en y". Además, al usar .keys () para hacer una lista de las claves del diccionario y dividir esa lista, evita 'tocar' las teclas innecesarias cuando crea el nuevo diccionario.
Si no necesita las claves (solo los valores), puede usar una lista de comprensión:
first2vals = [v for v in mydict.values()[:2]]
Si necesita los valores ordenados según sus claves, no hay mucho más problema:
first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]
o si también necesita las llaves:
first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}
Los dicts de Python no están ordenados, por lo que no tiene sentido pedir las "primeras N" claves.
La collections.OrderedDictclase está disponible si eso es lo que necesita. Puede obtener de manera eficiente sus primeros cuatro elementos como
import itertools
import collections
d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)
for key, value in x:
print key, value
itertools.islicele permite tomar perezosamente una porción de elementos de cualquier iterador. Si desea que el resultado sea reutilizable, deberá convertirlo en una lista o algo así:
x = list(itertools.islice(d.items(), 0, 4))
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
print(next(iterator))
Básicamente, convierta la vista (dict_items) en un iterador y luego itere con next ().
No lo vi aquí. No se ordenará, sino que será sintácticamente más simple si solo necesita tomar algunos elementos de un diccionario.
n = 2
{key:value for key,value in d.items()[0:n]}
TypeError: 'dict_items' object is not subscriptable {key:value for key,value in stocks.items()[0:n]} (existencias es el nombre de mi diccionario)
Para obtener los N elementos principales de su diccionario de Python, se puede usar la siguiente línea de código:
list(dictionaryName.items())[:N]
En tu caso puedes cambiarlo a:
list(d.items())[:4]
Consulte PEP 0265 sobre la clasificación de diccionarios. Luego use el código iterable mencionado anteriormente.
Si necesita más eficiencia en los pares clave-valor ordenados. Utilice una estructura de datos diferente. Es decir, uno que mantiene el orden ordenado y las asociaciones clave-valor.
P.ej
import bisect
kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))
print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
en py3, esto hará el truco
{A:N for (A,N) in [x for x in d.items()][:4]}
{'a': 3, 'b': 2, 'c': 3, 'd': 4}
Esto depende de lo que sea "más eficiente" en su caso.
Si solo desea una muestra semi-aleatoria de un diccionario enorme foo, use foo.iteritems()y tome tantos valores como necesite, es una operación perezosa que evita la creación de una lista explícita de claves o elementos.
Si necesita ordenar las claves primero, no hay forma de evitar usar algo como keys = foo.keys(); keys.sort()osorted(foo.iterkeys()) , tendrá que crear una lista explícita de claves. Entonces rebanar o iterar a través de primera N keys.
Por cierto, ¿por qué te preocupas por la forma "eficiente"? ¿Hiciste un perfil de tu programa? Si no lo hizo, utilice primero la forma obvia y fácil de entender . Es probable que funcione bastante bien sin convertirse en un cuello de botella.
Puede abordar esto de varias maneras. Si el orden es importante, puede hacer esto:
for key in sorted(d.keys()):
item = d.pop(key)
Si el orden no le preocupa, puede hacer esto:
for i in range(4):
item = d.popitem()
valuelugar de itempara mayor claridad.
El diccionario no mantiene ningún orden, por lo que antes de elegir los N pares de valores clave principales, hagámoslo ordenar.
import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values
Ahora podemos hacer la recuperación de los elementos 'N' superiores :, usando la estructura del método como esta:
def return_top(elements,dictionary_element):
'''Takes the dictionary and the 'N' elements needed in return
'''
topers={}
for h,i in enumerate(dictionary_element):
if h<elements:
topers.update({i:dictionary_element[i]})
return topers
para obtener los 2 elementos superiores, simplemente use esta estructura:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)
considerar un dictado
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
from itertools import islice
n = 3
list(islice(d.items(),n))
islice hará el truco :) espero que ayude!
Puede que esto no sea muy elegante, pero funciona para mí:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
x= 0
for key, val in d.items():
if x == 2:
break
else:
x += 1
# Do something with the first two key-value pairs
Probé algunas de las respuestas anteriores y noté que algunas de ellas dependen de la versión y no funcionan en la versión 3.7.
También observo que desde 3.6 todos los diccionarios están ordenados por la secuencia en la que se insertan los elementos.
A pesar de que los diccionarios se ordenaron desde 3.6, algunas de las declaraciones que espera que funcionen con estructuras ordenadas no parecen funcionar.
La respuesta a la pregunta de OP que mejor funcionó para mí.
itr = iter(dic.items())
lst = [next(itr) for i in range(3)]
lst = list(d.items())[:N]
list(d.items())[:4]. list () es la implementación subyacente para muchas de las respuestas.