2012-09-04 9 views
6

Digamos que tengo un diccionario:encontrar los mejores k teclas más grandes en un pitón diccionario

{key1:value1........... keyn:valuen} 

lo que permite decir que quiero escribir una función

def return_top_k(dictionary, k): 

    return list_of_keys_sorted 

¿Cuál es la forma más eficiente (en términos de O grande) para obtener las claves que tienen los valores k superiores (manteniendo el orden, es decir, la clave de valor más alto está presente al principio ... etc.)

+1

Cuando se habla de diccionarios usando 'k' para un conteo es confuso porque a menudo significa 'clave'. Use 'n' en su lugar. –

Respuesta

14

O(n log k):

import heapq 

k_keys_sorted = heapq.nlargest(k, dictionary) 

Usted podría utilizar key parámetro de palabra clave para especificar lo que debe ser utilizado como un ejemplo clave de clasificación:

k_keys_sorted_by_values = heapq.nlargest(k, dictionary, key=dictionary.get) 
+6

Creo que el OP realmente está pidiendo algo como 'heapq.nlargest (k, dictionary, key = dictionary .__ getitem __)': claves del diccionario ordenadas por sus valores. – Dougal

+1

Tenga en cuenta que este es un resultado para las claves de clasificación –

+0

@Dougal: 'list_of_keys_sorted' sugiere lo contrario – jfs

4
return sorted(dictionary, key=dictionary.get, reverse=True)[:10] 

debe ser por lo peor O(NlogN) (aunque heapq propuesto por los demás es probablemente mejor) ...

Se fuerza también tiene sentido utilizar un Counter en lugar de un diccionario tradicional. En ese caso, el método most_common hará (aproximadamente) lo que desee (dictionary.most_common(10)), pero solo si tiene sentido usar un Counter en su API.

+0

Esto es perfecto. Añadiré que si el diccionario pasa a un diccionario de conteos, 'collections.Counter' sería la estructura de datos correcta. Entonces la solución sería '[k para k, v en counts.most_common (10)]'. –

1

Para subir 3-paso a paso:

>>> from operator import itemgetter 
>>> dct = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} 
>>> sorted(dct.items(), key=itemgetter(1), reverse=True) 
[('e', 5), ('d', 4), ('c', 3), ('b', 2), ('a', 1)] 
>>> map(itemgetter(0), sorted(dct.items(), key=itemgetter(1), reverse=True)) 
['e', 'd', 'c', 'b', 'a'] 
>>> map(itemgetter(0), sorted(dct.items(), key=itemgetter(1), reverse=True))[:3] 
['e', 'd', 'c'] 

O usando heapq módulo

>>> import heapq 
>>> heapq.nlargest(3, dct.items(), key=itemgetter(1)) 
[('e', 5), ('d', 4), ('c', 3)] 
>>> map(itemgetter(0), _) 
['e', 'd', 'c'] 
1

En el código

dct = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5} 
k = 3 
print sorted(dct.keys(), reverse=True)[:k] 

Si también necesita valores:

print sorted(dct.items(), reverse=True)[:k] 

O si se desea utilizar OrderedDict:

from collections import OrderedDict 
d = OrderedDict(sorted(dct.items(), reverse=True)) 
print d.keys()[:k] 
1
portfolio = [ 
    {'name': 'IBM', 'shares': 100, 'price': 91.1}, 
    {'name': 'AAPL', 'shares': 50, 'price': 543.22}, 
    {'name': 'FB', 'shares': 200, 'price': 21.09}, 
    {'name': 'HPQ', 'shares': 35, 'price': 31.75}, 
    {'name': 'YHOO', 'shares': 45, 'price': 16.35}, 
    {'name': 'ACME', 'shares': 75, 'price': 115.65} 
] 

cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price']) 
expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price']) 
Cuestiones relacionadas