2009-05-19 27 views
10

si tengo una lista en Python como¿Cómo se calcula la mayor cantidad de repeticiones en una lista?

[1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1] 

¿Cómo se calcula el mayor número de repeticiones para cualquier elemento? En este caso, 2 se repite un máximo de 4 veces y 1 se repite un máximo de 3 veces.

¿Hay alguna manera de hacer esto pero también registrar el índice en el que comenzó la carrera más larga?

+0

Parece que está buscando la carrera más larga de la lista; Es posible que desee editar su pregunta para dejarlo en claro. – las3rjock

+2

Específicamente la ejecución más larga de cada número – Sparr

+0

Sí Sparr que es correcto. ¿Hay alguna manera de hacer esto pero también registrar el índice en el que comenzó la carrera más larga? – hekevintran

Respuesta

42

Uso groupby, él elementos del grupo por valor:

from itertools import groupby 
group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]) 
print max(group, key=lambda k: len(list(k[1]))) 

Y aquí está el código en acción:

>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1]) 
>>> print max(group, key=lambda k: len(list(k[1]))) 
(2, <itertools._grouper object at 0xb779f1cc>) 
>>> group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3]) 
>>> print max(group, key=lambda k: len(list(k[1]))) 
(3, <itertools._grouper object at 0xb7df95ec>) 

De la documentación de Python:

La operación de groupby() es similar al filtro uniq en Unix. Se genera una ruptura o grupo nuevo cada vez el valor de la función de la tecla cambia

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B 
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D 

Si también desea que el índice de la pista más larga, puede hacer lo siguiente:

group = groupby([1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 3, 3, 3, 3, 3]) 
result = [] 
index = 0 
for k, g in group: 
    length = len(list(g)) 
    result.append((k, length, index)) 
    index += length 

print max(result, key=lambda a:a[1]) 
+0

+1 - 'groupby' está hecho a medida para esto. –

+0

¿Hay alguna manera de hacerlo y también registrar el índice en el que comenzó la ejecución más larga? ¡Gracias! – hekevintran

+0

Actualicé la respuesta con una solución para obtener el índice también –

0

Este código parece funcionar:

l = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1] 
previous = None 

# value/repetition pair 
greatest = (-1, -1) 
reps = 1 

for e in l: 
    if e == previous: 
     reps += 1 
    else: 
     if reps > greatest[1]: 
      greatest = (previous, reps) 

     previous = e 
     reps = 1 

if reps > greatest[1]: 
    greatest = (previous, reps) 

print greatest 
+0

+1 por golpearme. – geowa4

+3

eso no es lo que OP está pidiendo – SilentGhost

+0

OP incluso dio el caso de prueba ... cuyos resultados no coinciden ... –

0

que haría uso de un mapa hash del elemento de contrarrestar.

Cada vez que vea una sucesión 'clave', incremente su valor de contador. Si tocas un nuevo elemento, establece el contador en 1 y continúa. Al final de esta búsqueda lineal, debe tener el recuento de sucesión máximo para cada número.

3

Pasa por la lista, realiza un seguimiento del número actual, cuántas veces se ha repetido, y compara la cantidad de veces que has visto ese número repetido.

Counts={} 
Current=0 
Current_Count=0 
LIST = [1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1] 
for i in LIST: 
    if Current == i: 
     Current_Count++ 
    else: 
     Current_Count=1 
     Current=i 
    if Current_Count>Counts[i]: 
     Counts[i]=Current_Count 
print Counts 
1

Si lo desea solo para cualquier elemento (es decir, el elemento con más repeticiones), puede usar:

def f((v, l, m), x): 
    nl = l+1 if x==v else 1 
    return (x, nl, max(m,nl)) 

maxrep = reduce(f, l, (0,0,0))[2]; 

Esto solo cuenta repeticiones continuas (el resultado para [1,2,2,2,1,2] sería 3) y solo registra el elemento con el número máximo.

Editar: Hecho definición de fa poco más corto ...

+0

¿Parece relacionado con muchas cosas de Perl? ;) –

1

Esta es mi solución:

def longest_repetition(l): 
    if l == []: 
     return None 

    element = l[0] 
    new = [] 
    lar = [] 

    for e in l:    
     if e == element: 
      new.append(e) 
     else: 
      if len(new) > len(lar): 
       lar = new 
      new = [] 
      new.append(e) 
      element = e 
    if len(new) > len(lar): 
     lar = new  
    return lar[0] 
1

-Se puede hacer la nueva copia de la lista, pero con valores únicos y una correspondiente éxitos lista.

-Entonces obtenga la lista Máx. De visitas y obtenga de su índice su artículo más repetido.

oldlist = ["A", "B", "E", "C","A", "C","D","A", "E"] 
newlist=[] 
hits=[] 
for i in range(len(oldlist)): 
    if oldlist[i] in newlist: 
     hits[newlist.index(oldlist[i])]+= 1 
    else: 
     newlist.append(oldlist[i]) 
     hits.append(1); 
#find the most repeated item 
temp_max_hits=max(hits) 
temp_max_hits_index=hits.index(temp_max_hits) 
print(newlist[temp_max_hits_index]) 
print(temp_max_hits) 

Pero no sé si es la forma más rápida de hacerlo o hay una solución más rápida. Si cree que hay una solución más rápida o más eficiente, infórmenos amablemente.

Cuestiones relacionadas