„Splitting“, die Ausgabe eines RLE (groupby) in Abhängigkeit von einem definierten Wert (das „Zeichen“ auf die RLE aufzuspalten)
Frage
Betrachten Sie den "string" (behandeln es als eine Reihe von Ziffern)
0 0 1 8 8 8 1 0
Die RLE ( "groupby") lautet:
[(0,2), (1, 1), (8,3), (1, 1), (0, 1)]
Wir bereichern dann die oben RLE mit der Summe der Lauflängen der vorhergehenden Elemente.
Damit die angereicherte Version des obigen wird:
[(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))]
Das "string" split auf 1:
0 0 , 8 8 8 , 0
RLE Split auf 1
[(0,2)] , [(8,3)] , [(0, 1)]
Das "string" split auf 8:
0 0 1 , , , 1 0
RLE Split auf 8
[(0,2), (1, 1)] , , , [(1, 1), (0, 1)]
Hinweis: In meinen Beispielen habe ich die „RLE Split auf Z“ Listen zitiert, ohne sie zu bereichern. Dies würde nicht so sein. Ich ließ sie Unordnung reduzieren heraus. Zum Beispiel sollte das „RLE Split auf 1“ wirklich behandelt wie:
[(0, (0,2))] , [(0+2+1, (8,3))] , [(0+1+2+3+1, (0, 1)]
Wie kann ich dieses "RLE split" auf Z erreichen (= 1, 8; in diesem Fall)
Es ist in Ordnung leere Arrays auszulassen (nach Split).
Vielleicht eine kluge Liste comp.? (Es scheint ein wenig leichter mit einem for-Schleife zu lösen mit einer append verschachtelt innerhalb)
Lösung
Just for Show die Art und Weise, wie ich Ihnen dringend raten, nicht diesen
zu verwenden,"elegant" hässliche Art und Weise:
>>> 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))]]
Andere Tipps
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))]]