2012-08-10 17 views
20

¿Cómo recupero la lista de los 3 primeros de un diccionario?principales valores del diccionario

>>> d 
{'a': 2, 'and': 23, 'this': 14, 'only.': 21, 'is': 2, 'work': 2, 'will': 2, 'as': 2, 'test': 4} 

Resultado esperado:

and: 23 
only: 21 
this: 14 

Respuesta

29

Uso collections.Counter:

>>> d = Counter({'a': 2, 'and': 23, 'this': 14, 'only.': 21, 'is': 2, 'work': 2, 'will': 2, 'as': 2, 'test': 4}) 
>>> d.most_common() 
[('and', 23), ('only.', 21), ('this', 14), ('test', 4), ('a', 2), ('is', 2), ('work', 2), ('will', 2), ('as', 2)] 
>>> for k, v in d.most_common(3): 
...  print '%s: %i' % (k, v) 
... 
and: 23 
only.: 21 
this: 14 

objetos de contador ofrecen otras ventajas, como por lo que es casi trivial para recoger los recuentos en el primer lugar.

16
>>> d = {'a': 2, 'and': 23, 'this': 14, 'only.': 21, 'is': 2, 'work': 2, 'will': 2, 'as': 2, 'test': 4} 
>>> t = sorted(d.iteritems(), key=lambda x:-x[1])[:3] 

>>> for x in t: 
...  print "{0}: {1}".format(*x) 
... 
and: 23 
only.: 21 
this: 14 
+0

Acepta que Counter es una mejor forma de hacerlo si quieres contar las cosas también. Pero si solo quieres los 3 mejores valores en un dict ya creado, parece una exageración. :) –

+0

Eso depende del tamaño del diccionario. La ordenación del diccionario es O (n log n), la creación de un contador y la extracción de 'k' más grande es solo O (n log k). Para grandes 'n' y pequeñas' k' que hacen que la opción de Contador sea mucho más eficiente. – Duncan

+0

En realidad, solo por 3 valores superiores, utilizaría la función 'heapq.nlargest()'; es más eficiente que ordenar la secuencia completa. Eso es lo que 'Counter()' usa internamente. –

0

Las respuestas que ya recibió son correctas, sin embargo, crearía mi propia función de tecla para usar cuando call sorted().

d = {'a': 2, 'and': 23, 'this': 14, 'only.': 21, 'is': 2, 'work': 2, 'will': 2, 'as': 2, 'test': 4} 

# create a function which returns the value of a dictionary 
def keyfunction(k): 
    return d[k] 

# sort by dictionary by the values and print top 3 {key, value} pairs 
for key in sorted(d, key=keyfunction, reverse=True)[:3]: 
    print "%s: %i" % (key, d[key]) 
1

Dadas las soluciones anteriores:

def most_popular(L): 
    # using lambda 
    start = datetime.datetime.now() 
    res=dict(sorted([(k,v) for k, v in L.items()], key=lambda x: x[1])[-2:]) 
    delta=datetime.datetime.now()-start 
    print "Microtime (lambda:%d):" % len(L), str(delta.microseconds) 

    # using collections 
    start=datetime.datetime.now() 
    res=dict(collections.Counter(L).most_common()[:2]) 
    delta=datetime.datetime.now()-start 
    print "Microtime (collections:%d):" % len(L), str(delta.microseconds) 

# list of 10 
most_popular({el:0 for el in list(range(10))}) 

# list of 100 
most_popular({el:0 for el in list(range(100))}) 

# list of 1000 
most_popular({el:0 for el in list(range(1000))}) 

# list of 10000 
most_popular({el:0 for el in list(range(10000))}) 

# list of 100000 
most_popular({el:0 for el in list(range(100000))}) 

# list of 1000000 
most_popular({el:0 for el in list(range(1000000))}) 

de trabajo en dict conjunto de datos de tamaño de 10^1 a 10^6 dict de objetos como

print {el:0 for el in list(range(10))} 
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0} 

tenemos los siguientes puntos de referencia

Python 2.7.10 (default, Jul 14 2015, 19:46:27) 
[GCC 4.8.2] on linux 

Microtime (lambda:10): 24 
Microtime (collections:10): 106 
Microtime (lambda:100): 49 
Microtime (collections:100): 50 
Microtime (lambda:1000): 397 
Microtime (collections:1000): 178 
Microtime (lambda:10000): 4347 
Microtime (collections:10000): 2782 
Microtime (lambda:100000): 55738 
Microtime (collections:100000): 26546 
Microtime (lambda:1000000): 798612 
Microtime (collections:1000000): 361970 
=> None 

Así que podemos digamos que para listas pequeñas, use lambda, pero para obtener una lista enorme, collections tiene mejores resultados.

Consulte el punto de referencia ejecutando here.

Cuestiones relacionadas