2010-10-19 10 views
6

tengo una lista de la siguiente manera:Python: determinar la longitud de secuencia de elementos iguales en la lista

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2] 

quiero para determinar la longitud de una secuencia de elementos iguales, es decir, para la lista dada quiero la salida ser:

[(0, 6), (1, 6), (0, 4), (2, 3)] 

(o un formato similar).

Pensé en usar un defaultdict pero cuenta las ocurrencias de cada elemento y lo acumula para toda la lista, ya que no puedo tener más de una clave '0'.

En este momento, mi solución es similar a esto:

out = [] 
cnt = 0 

last_x = l[0] 
for x in l: 
    if x == last_x: 
     cnt += 1 
    else: 
     out.append((last_x, cnt)) 
     cnt = 1 
    last_x = x 
out.append((last_x, cnt)) 

print out 

Me pregunto si hay una manera más Pythonic de hacer esto.

Respuesta

13

Es casi seguro que desea utilizar itertools.groupby:

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2] 
answer = [] 
for key, iter in itertools.groupby(l): 
    answer.append((key, len(list(iter)))) 

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)] 

Si desea hacerlo más eficiente de la memoria, sin embargo, añadir más complejidad, se puede añadir una función de longitud:

def length(l): 
    if hasattr(l, '__len__'): 
     return len(l) 
    else: 
     i = 0 
     for _ in l: 
      i += 1 
     return i 

l = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2] 
answer = [] 
for key, iter in itertools.groupby(l): 
    answer.append((key, length(iter))) 

# answer is [(0, 6), (1, 6), (0, 4), (2, 3)] 

Nota aunque que no he comparado la función length(), y es muy posible que te ralentice.

+0

Puede acelerar un poco la cláusula 'else:' reemplazando lo que se muestra con las dos líneas siguientes: 'for i, _ en enumerate (l, 1): pass' seguido de' return i'. – martineau

3

la respuesta de Mike es bueno, pero el itertools._grouper devuelto por GroupBy nunca tendrá un método __len__ lo que no hay pruebas de que el punto de

utilizo sum(1 for _ in i) para obtener la longitud de la itertools._grouper

>>> import itertools as it 
>>> L = [0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,2,2,2] 
>>> [(k, sum(1 for _ in i)) for k, i in it.groupby(L)] 
[(0, 6), (1, 6), (0, 4), (2, 3)] 
+1

. . . ¡muy agradable! – mshsayem

Cuestiones relacionadas