2011-05-18 17 views
8

Tengo una lista de enteros; por ejemplo:Recuento de ocurrencias en una lista de Python

l = [1, 2, 3, 4, 4, 4, 1, 1, 1, 2] 

que estoy tratando de hacer una lista de los tres elementos en l con el mayor número de apariciones, en orden decreciente de frecuencia. Entonces en este caso quiero la lista [1, 4, 2], porque 1 ocurre más en l (cuatro veces), 4 es el siguiente con tres instancias, y luego 2 con dos. Solo quiero los primeros tres resultados, por lo que 3 (con solo una instancia) no aparece en la lista.

¿Cómo puedo generar esa lista?

+3

Los índices comienzan en 0. – delnan

Respuesta

19

Utilice un collections.Counter:

import collections 
l= [1 ,2 ,3 ,4,4,4 , 1 ,1 ,1 ,2] 

x=collections.Counter(l) 
print(x.most_common()) 
# [(1, 4), (4, 3), (2, 2), (3, 1)] 

print([elt for elt,count in x.most_common(3)]) 
# [1, 4, 2] 

collections.Counter se introdujo en Python 2.7. Si está utilizando una versión anterior, puede usar the implementation here.

+0

Vaya, Python sigue teniendo implementado todo lo que necesita. Solo notaré que necesitas una versión suficientemente nueva de Python para que esto funcione. Si está ejecutando 2.6, todavía no tiene Counter. –

+4

'x.most_common (3)' funciona también, no necesita cortar. –

+0

@Jochen Ritzel: Ah, muchas gracias. – unutbu

6
l_items = set(l) # produce the items without duplicates 
l_counts = [ (l.count(x), x) for x in set(l)] 
# for every item create a tuple with the number of times the item appears and 
# the item itself 
l_counts.sort(reverse=True) 
# sort the list of items, reversing is so that big items are first 
l_result = [ y for x,y in l_counts ] 
# get rid of the counts leaving just the items 
2
from collections import defaultdict 
l= [1 ,2 ,3 ,4,4,4 , 1 , 1 ,1 ,2] 
counter=defaultdict(int) 
for item in l: 
    counter[item]+=1 

inverted_dict = dict([[v,k] for k,v in counter.items()]) 

for count in sorted(inverted_dict.keys()): 
    print inverted_dict[count],count 

Esto debería imprimir la más frecuenta artículos en 'L': lo que se necesita para restringir a los tres primeros. Tenga cuidado al usar el inverted_dict allí (es decir, las claves y los valores se intercambian): esto dará como resultado una sobrescritura de valores (si dos elementos tienen conteos idénticos, solo se escribirá uno en el dict).

1

sin utilizar colecciones:

a = reversed(sorted(l,key=l.count)) 
outlist = [] 
for element in a: 
    if element not in outlist: 
    outlist.append(element) 

La primera línea le consigue que todos los elementos originales ordenados por recuento.

El bucle for es necesario para uniquify sin perder el orden (puede haber una manera mejor).

+1

'key = l.count' es desagradable: significa que haces n pases cuadrados a través de toda la lista (para cada elemento, cuenta el número de ocurrencias de ese elemento). Es mucho mejor usar una de las soluciones 'collection.Counter' o similares que usan un solo pase para generar los conteos. – Duncan

+0

@Duncan cierto, ¡no había pensado en la complejidad! Gracias por señalar eso. –

Cuestiones relacionadas