“División” la salida de un RLE (GroupBy) en función de un valor definido (el “carácter” para dividir el RLE en)

StackOverflow https://stackoverflow.com/questions/4308528

Pregunta

Considere el "string" (lo tratan como una serie de dígitos)

0 0 1 8 8 8 1 0

La RLE ( "GroupBy") es:

[(0,2), (1, 1), (8,3), (1, 1), (0, 1)]

A continuación, enriquecer el RLE anterior con la suma de las longitudes de secuencia de los elementos anteriores.

Por lo tanto, la versión enriquecida de lo anterior se convierte en:

[(0, (0,2)), (0+2, (1, 1)), (0+2+1, (8,3)), (0+1+2+3, (1, 1)), (0+1+2+3+1, (0, 1))]

La "cadena" dividida en 1:

0 0 , 8 8 8 , 0

Split RLE en 1

[(0,2)] , [(8,3)] , [(0, 1)]

La "cadena" dividida en 8:

0 0 1 , , , 1 0

RLE dividida en 8

[(0,2), (1, 1)] , , , [(1, 1), (0, 1)]

Nota: En los ejemplos, he citado la "fracción de RLE en Z" listas sin enriqueciéndolos. Esto no sería así. Los dejé a cabo para reducir el desorden. Por ejemplo, el "split RLE en 1" en realidad debería ser tratada como:

[(0, (0,2))] , [(0+2+1, (8,3))] , [(0+1+2+3+1, (0, 1)]

¿Cómo puedo lograr este "split RLE" en Z (= 1, 8; en este caso)

Está bien dejar fuera matrices vacías (después de la división).

Tal vez una lista inteligente comp.? (Parece un poco más fácil de resolver con un bucle con un append anidado dentro)

¿Fue útil?

Solución

Sólo para la demostración de la manera cómo, yo recomiendo que no use este

"elegante" fea manera:

>>> data
[0, 0, 1, 8, 8, 8, 4, 4, 1, 0]
>>> def fromDataToSplitRLE(dat,n):
    RLE=[(k,len(tuple(g))) for k,g in itertools.groupby(dat)]
    tmp=tuple(zip(*RLE))
    return [list(g) for k,g in itertools.groupby((zip((sum(tmp[1][:i]) for i in range(len(tmp[1]))) ,(zip(*tmp)))),lambda x:x[1][0]!=n) if k]

>>> fromDataToSplitRLE(data,1)
[[(0, (0, 2))], [(3, (8, 3)), (6, (4, 2))], [(9, (0, 1))]]

Otros consejos

import itertools

def get_rle(list_of_digits, split_on=None):
    count = 0
    rle = []
    active_group = []
    rle_app = rle.append
    for item, group in itertools.groupby(list_of_digits):
        L = len(list(group))
        if item == split_on:
            rle_app(active_group)
            active_group = []
        else:
            active_group.append((count, (item, L)))
        count += L

    rle_app(active_group)
    return rle

list_of_digits = map(int, '0 0 1 8 8 8 1 0'.split())
print get_rle(list_of_digits)
print get_rle(list_of_digits, 8)
print get_rle(list_of_digits, 1)

aaron@aaron-laptop:~/code/tmp$ python rle.py
[[(0, (0, 2)), (2, (1, 1)), (3, (8, 3)), (6, (1, 1)), (7, (0, 1))]]
[[(0, (0, 2)), (2, (1, 1))], [(6, (1, 1)), (7, (0, 1))]]
[[(0, (0, 2))], [(3, (8, 3))], [(7, (0, 1))]]
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top