2011-11-01 12 views

Respuesta

54

No existen las "primeras n" claves porque dict no recuerda qué claves se insertaron primero.

Puede obtener cualquier par n de valores clave embargo:

n_items = take(n, d.iteritems()) 

Esto utiliza la implementación de take del itertools recipes:

from itertools import islice 

def take(n, iterable): 
    "Return first n items of the iterable as a list" 
    return list(islice(iterable, n)) 

ver su funcionamiento en línea: ideone

+6

Creo 'iteritems' deben ser reemplazados con' 'de los artículos para la gente en Python 3 –

8

Python's dict s no están ordenados, por lo que no tiene sentido pedir el " primeras N "teclas.

La clase collections.OrderedDict está disponible si eso es lo que necesita. Usted podría conseguir 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.islice le permite tomar perezosamente una rebanada de elementos de cualquier iterador. Si desea que el resultado sea reutilizable que había necesidad de convertirlo en una lista o algo así, de este modo:

x = list(itertools.islice(d.items(), 0, 4)) 
0

Usted puede acercarse a esto un número de maneras. Si la orden es importante que usted puede hacer esto:

for key in sorted(d.keys()): 
    item = d.pop(key) 

si el orden no es una preocupación que puede hacer esto:

for i in range(4): 
    item = d.popitem() 
+0

En el primer fragmento probablemente debería llamarlo' valor 'en lugar de' elemento' para mayor claridad. – agf

3

Ver PEP 0265 en la clasificación de los diccionarios. Luego usa el código iterable antes mencionado.

Si necesita más eficiencia en los pares clave-valor ordenados. Usa una estructura de datos diferente. Es decir, uno que mantiene el orden ordenado y las asociaciones de valores-clave.

E.g.

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)] 
0

Esto depende de qué es "más eficiente" en su caso.

Si solo quiere una muestra semialeatoria de un enorme diccionario 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 primero tiene que ordenar las claves, no hay forma de evitar el uso de algo como keys = foo.keys(); keys.sort() o sorted(foo.iterkeys()), tendrá que crear una lista explícita de claves. A continuación, corte o itere primero N keys.

BTW ¿por qué le preocupa la forma "eficiente"? ¿Hiciste un perfil de tu programa?Si no lo hizo, primero use obvio y fácil de entender. Lo más probable es que funcionará bastante bien sin convertirse en un cuello de botella.

+0

Esta fue una aplicación para un programa financiero e intento crear cada línea de código de la manera más eficiente posible. No perfilé el programa y estoy de acuerdo en que probablemente no sea un cuello de botella, pero me gusta pedir soluciones eficientes por defecto. Gracias por la respuesta. –

23

Una manera muy eficiente de recuperar algo es combinar la lista o las comprensiones del diccionario con el corte. Si no es necesario pedir los artículos (lo que desea pares n al azar), se puede utilizar un diccionario por comprensión de esta manera:

# Python 2 
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]} 
# Python 3 
first2pairs = {k: mydict[k] for k in list(mydict)[:2]} 

En general, una comprensión como este es siempre más rápido en ejecutarse que el equivalente "para x en y "loop. Además, al usar .keys() para hacer una lista de las teclas del diccionario y cortar esa lista, evita "tocar" las teclas innecesarias cuando construye el nuevo diccionario.

Si usted no necesita las teclas (sólo los valores) se puede utilizar una lista por comprensión:

first2vals = [v for v in mydict.values()[:2]] 

Si necesita los valores ordenados en base a sus llaves, no hay mucho más problemas:

first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]] 

o si necesita las llaves, así:

first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]} 
+0

Esta es una mejor solución si desea seleccionar N muchos pares clave: valor como un diccionario, no como una lista – fermat4214

+0

@ fermat4214 ¿Es un problema si mi diccionario completo se imprime cuando ejecuto alguno de estos comandos? –

3

no lo vi aquí. No se ordenará sino que será más simple sintácticamente si solo necesita tomar algunos elementos de un diccionario.

n = 2 
{key:value for key,value in d.items()[0:n]} 
+2

He intentado codificar pero recibo este error: 'TypeError: 'objeto de dict_items' no es subscriptible' ' {clave: valor de la clave, valor en stocks.items() [0: n]} '(stocks es el nombre de mi diccionario) – Moondra

0

Diccionario no mantiene ningún orden, por lo que antes de elegir los mejores pares de valores de la clave N, hagámoslo.

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 elementos superiores 'N' :, utilizando la estructura método como este:

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 la parte superior de 2 elementos, entonces simplemente utilizar 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) 
0
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, gire la vista (dict_items) en un iterador, y entonces iterar con next().

0
Para

Python 3 y superior, para seleccionar los n primeros pares

n=4 
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]} 
Cuestiones relacionadas