2015-10-21 3 views
-1

Мне нужно написать программу, которая использует кодирование длины пробега для сжатия списка. Я понятия не имею, как это сделать и немного изменив мою программу, я даже не знаю, что она делает сейчас.Функция кодирования длины пробега (без библиотек или методов объекта)

Нам не разрешено импортировать и библиотеки, а также использовать методы строки или списка объектов python (например, append()).

Это довольно много, где я сейчас нахожусь:

def rle(x): 
    c_list = [] 
    count = 0 
    for num in x: 
     if x[num] == x[num - 1]: 
      c+=[x[num], count] 
      count+= 1 
    # ... 
    return c 

, используя этот список в качестве примера:

[8,8,8,4,5,5,5,6,6,6,6,9,8,1,1,1,1,3,3] 

Это будет возвращать это:

[6, 0, 6, 1, 6, 2, 5, 3, 5, 4, 5, 5, 5, 6, 
5, 7, 5, 8, 5, 9, 6, 10, 6, 11, 8, 12, 8, 
13, 8, 14, 8, 15] 

который, очевидно, далеко.

+0

Что он должен вернуть? –

+0

он должен вернуть сжатый список: [8,3,4,1,5,3 ...] – Nick

ответ

1

Какая кодировка должна быть? Предполагая, что кортежи (element, count), то вы могли бы реализовать генератор:

def rle(iterable): 
    it = iter(iterable) 
    e, c = next(it), 1  # StopIteration silently handled before Py3.7 
    for n in it: 
     if n == e: 
      c += 1 
      continue 
     yield (e, c)   # "yield from (e, c)" if you need a flat list 
     e, c = n, 1 
    yield (e, c) 

>>> list(rle('aaaaaddddffgghjjjjj')) 
[('a', 5), ('d', 4), ('f', 2), ('g', 2), ('h', 1), ('j', 5)] 
>>> list(rle([8,8,8,4,5,5,5,6,6,6,6,9,8,1,1,1,1,3,3])) 
[(8, 3), (4, 1), (5, 3), (6, 4), (9, 1), (8, 1), (1, 4), (3, 2)] 
+0

Я не знаком с «except», «StopIteration» и «try», поэтому мне сложно следуя программе – Nick

+0

'try: except:' позволяет обрабатывать исключения, 'next (it)' может вызывать исключение 'StopIteration', если вы передаете пустой итерабельный. В настоящее время вам не нужен блок try, потому что quirk генераторов молча обрабатывает исключения 'StopIteration' до Py3.7. Я обновлю код, чтобы удалить блок try - он был там только для будущей проверки, учитывая, что мы только на Py3.5 – AChampion

0
def rle(x): 
    prev = x[0] 
    count = 0 
    for item in x: 
     if item == prev: 
      count += 1 
     else: 
      yield prev, count 
      prev = item 
      count = 1 
    yield prev, count 

x = [8,8,8,4,5,5,5,6,6,6,6,9,8,1,1,1,1,3,3] 
print list(rle(x)) 

печатает

[(8, 3), (4, 1), (5, 3), (6, 4), (9, 1), (8, 1), (1, 4), (3, 2)] 

Если вам нужно

[8, 3, 4, 1, 5, 3, 6, 4, 9, 1, 8, 1, 1, 4, 3, 2] 

просто заменить каждый yield с 2 yields

yield prev 
yield count 
+1

, что такое 'start' for, он, похоже, не используется. И, возможно, потребуется защититься от пустого списка. – AChampion