0

considérer la « chaîne » (le traiter comme un tableau de chiffres)« splitting » la sortie d'un RLE (groupby) en fonction d'une valeur définie (le « caractère » pour diviser le RLE sur)

0 0 1 8 8 8 1 0 

le RLE (« groupby ») est:

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

Nous enrichissons alors la RLE ci-dessus avec la somme des longueurs d'exécution des éléments précédents.

Par conséquent, la version enrichie de ce qui précède devient:

[(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 division "string" sur 1:

0 0 , 8 8 8 , 0 

RLE divisée sur 1

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

La « chaîne "split on 8:

Dans mes exemples, j'ai cité le "split RLE sur Z" listes sans les enrichir:

RLE divisé sur 8

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

Remarque. Ce ne serait pas le cas. Je les ai laissés dehors pour réduire l'encombrement. Par exemple, le "RLE fendu sur 1" devrait vraiment être traitée comme:

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

Comment puis-je obtenir ce "RLE split" sur Z (= 1, 8, dans ce cas)

C'est bien d'omettre les tableaux vides (après la division).

Peut-être une liste intelligente? (Il semble un peu plus facile à résoudre avec une boucle avec un append imbriqué dans)

+1

Je suis confus. Est-ce qu'une expression comme '0 + 2 + 1' est censée être une chaîne ou voulez-vous simplement' 3'? – aaronasterling

+0

Juste 3 - Je voulais décomposer les choses pour être lisibles. Désolé pour la confusion! – PoorLuzer

+0

Supposons que RLE = [(0,2), (1,1), (8,3), (4,2), (1,1), (0,1)]; Si le résultat est [(0, (0,2))], [(0 + 2 + 1, (8,3), ** (4,2) **)], [(0 + 2 + 1 + 3 + 2 + 1, (0, 1)] ou [(0, (0,2))], [(0 + 2 + 1, (8,3)), ** (0 + 2 + 1 + 3 , (4,2)) **], [(0 + 2 + 1 + 3 + 2 + 1, (0, 1)] – Kabie

Répondre

1

Juste pour montrer la voie comment, je vous conseille fortement de ne pas utiliser cette

façon laide « élégante »:

>>> 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))]] 
+1

@ Aaronasterling: Eh bien, je l'ai mal compris. Je vais l'améliorer. – Kabie

+0

Je voudrais beaucoup vous voir accomplir cela avec une compréhension de la liste. – aaronasterling

+0

Notez que cela nécessite deux appels groupby. Cependant, il effectue correctement le découpage sans traitement supplémentaire, alors que celui d'Aaron nécessitera un passage supplémentaire sur None. – PoorLuzer

1
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) 

[email protected]aron-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))]] 
+0

Je l'avais déjà écrit (et sans le None.) J'ai mentionné * "C'est bien d'omettre les tableaux vides (après split). "*) C'est pourquoi j'ai commenté *" (il semble un peu plus facile à résoudre avec une boucle for avec un appendice imbriqué) "* - ** Je cherche quelque chose de plus rapide - comme une liste compr. Des idées? – PoorLuzer

+1

@PoorLuzer. Voir ma note à la fin. Je viens de l'éditer. Cela va aller beaucoup plus vite. – aaronasterling

+2

In (count, (item, L)), count doit être l'index de départ, donc plus L après l'instruction if – Kabie