Я использовал groupby
функцию из itertools
модуля.
Также я использовал window
функцию от здесь .
from __future__ import print_function
from itertools import tee, izip, groupby
a = [255,1,255,255,1,255,255,255,2,2,255,255,255,2,2,3,255,255,255,3]
def groupby2(iterable):
'''Used to convert to the second iterable element of "groupby" result to list'''
for i in groupby(iterable):
yield (i[0],list(i[1]))
def window(iterable,n):
els = tee(iterable,n)
for i,el in enumerate(els):
for _ in range(i):
next(el, None)
return izip(*els)
def compress(iterable):
it = window(groupby2(iterable),3)
#Creates the iterator which yield the elements in the following manner: (255, [255]), (1, [1]), (255, [255, 255])
for ge in it:
flag = False #Reset the flag
print('\nWindow: {}'.format(ge))
for value in ge[0][1]: #Yield all the values of the first element of the window
print('A: {}'.format(value))
yield value
if ge[1][0]==255 and ge[0][0]==ge[2][0]: #The central element of the window has to be replaced
flag = True #Flag for correct last window processing
for _ in ge[1][1]: #Replacing the central element of the window
print('B: {}'.format(ge[0][0]))
yield ge[0][0]
next(it,None) #Skip 1 element of the 'it' (which will be advanced by 1 element by for-loop, giving 2 net advances).
#Processing the last 2 elements of the last window.
if flag==False: #The central element of the last window hasn't been processed. Proccessing.
for value in ge[1][1]:
print('C: {}'.format(value))
yield value
for value in ge[2][1]: #The last element of the window.
print('D: {}'.format(value))
yield value
print('\nInput: {}'.format(a))
output = list(compress((a)))
print('Proram output: {}'.format(output))
print('Goal output : {}'.format([255,1,1,1,1,255,255,255,2,2,2,2,2,2,2,3,3,3,3,3]))
Код с сообщениями отладки. Я проживу их здесь, так как они облегчают понимание того, как это работает. Просто удалите их, если они вам не нужны.
Вывод:
Input: [255, 1, 255, 255, 1, 255, 255, 255, 2, 2, 255, 255, 255, 2, 2, 3, 255, 255, 255, 3]
Window: ((255, [255]), (1, [1]), (255, [255, 255]))
A: 255
Window: ((1, [1]), (255, [255, 255]), (1, [1]))
A: 1
B: 1
B: 1
Window: ((1, [1]), (255, [255, 255, 255]), (2, [2, 2]))
A: 1
Window: ((255, [255, 255, 255]), (2, [2, 2]), (255, [255, 255, 255]))
A: 255
A: 255
A: 255
Window: ((2, [2, 2]), (255, [255, 255, 255]), (2, [2, 2]))
A: 2
A: 2
B: 2
B: 2
B: 2
Window: ((2, [2, 2]), (3, [3]), (255, [255, 255, 255]))
A: 2
A: 2
Window: ((3, [3]), (255, [255, 255, 255]), (3, [3]))
A: 3
B: 3
B: 3
B: 3
D: 3
Proram output: [255, 1, 1, 1, 1, 255, 255, 255, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
Goal output : [255, 1, 1, 1, 1, 255, 255, 255, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3]
Обновление
Вот пересмотренная версия:
from __future__ import print_function
from itertools import tee, izip, groupby
def groupby2(iterable):
for i in groupby(iterable):
yield (i[0],len(tuple(i[1])))
def window(iterable,n):
els = tee(iterable,n)
for i,el in enumerate(els):
for _ in range(i):
next(el, None)
return izip(*els)
def subs(iterable):
it = window(groupby2(iterable),3)
for left, middle, right in it:
yield [left[0]]*left[1]
if middle[0]==255 and left[0]==right[0]:
yield [left[0]]*middle[1]
next(it,None)
if not(middle[0]==255 and left[0]==right[0]):
yield [middle[0]]*middle[1]
yield [right[0]]*right[1]
def chained(iterable):
for L in subs(iterable):
for el in L:
yield el
a = [255,1,255,255,1,255,255,255,2,2,255,255,255,2,2,3,255,255,255,3]
print('\nInput: {}'.format(a))
output = list(chained((a)))
print('Proram output: {}'.format(output))
print('Goal output : {}'.format([255,1,1,1,1,255,255,255,2,2,2,2,2,2,2,3,3,3,3,3]))