2017-01-17 13 views
-1

Я борюсь с приведенным ниже списком, пытающимся заменить каждый блок 0s на предыдущий символ. Я хотел бы использовать регулярное выражение или использовать его решение itertools.как использовать итераторы для замены блока повторяющихся целых чисел с предшествующей строкой

ss1=['k', 0, 0, 0, 'z', 0, 0, 0, 0, 'c','p', 0, 0] 

В списке, в котором я работаю, содержится несколько тысяч наименований. Желаемый результат: [k,k,k,k,z,z,z,z,z,c,p,p,p...] Большое спасибо!

Мне было просто интересно, как это делается с помощью регулярных выражений или itertools. Нет ничего плохого в использовании цикла for и переменной для запоминания последнего предыдущего значения, отличного от 0.

+0

Что вы имеете в виду * решение на основе итераторов * la: оценка zy или понимание списка? –

+0

с использованием модуля itertools – el347

+0

Что не так, чтобы использовать цикл for и переменную для запоминания последнего предыдущего значения, отличного от 0? –

ответ

4

Вы можете использовать accumulate для этого:

result = itertools.accumulate(ss1,lambda x,y: x if y == 0 else y) 

Код работает следующим образом: accumulate принимает список [p0,p1,p2,...,pn] и всегда излучает первый p0, поэтому у нас все хорошо с тем.

Затем он вызывает функцию f (здесь lambda x,y: x if y == 0 else y) с p0 и p1. В нашей функции мы проверяем, является ли p10, если это так, мы возвращаем p0, и в противном случае мы берем новое значение (и возвращаем p1).

Теперь в следующей итерации, accumulate вызовы снова f, но теперь с результатом предыдущей итерации и p2, и поэтому у нас есть алгоритм ScanLine, который держит излучающие предыдущий пункт, пока не ноль не подается в секунду аргумент.

Если я запускаю это в Python:

>>> result = itertools.accumulate(ss1,lambda x,y: x if y == 0 else y) 
>>> list(result) 
['k', 'k', 'k', 'k', 'z', 'z', 'z', 'z', 'z', 'c', 'p', 'p', 'p'] 
2

Вероятно, это также возможно с помощью itertools но простой генератор может быть использован, а также:

def replace_following_zeros(iterable): 
    it = iter(iterable) 
    item = next(it) 
    yield item 
    while True: 
     item2 = next(it) 
     if item2 != 0: 
      item = item2 
     yield item 

>>> list(replace_following_zeros(ss1)) 
['k', 'k', 'k', 'k', 'z', 'z', 'z', 'z', 'z', 'c', 'p', 'p', 'p'] 
1

В то время как вы могли бы использовать itertools, довольно простой генераторный подход также будет работать:

>>> def fill(seq): 
...  last_el = None 
...  for el in seq: 
...   if isinstance(el, str): 
...    last_el = el if last_el != el else last_el 
...   yield last_el if last_el else el 
... 
>>> L = ['k', 0, 0, 0, 'z', 0, 0, 0, 0, 'c', 'p', 0, 0] 
>>> list(fill(L)) 
['k', 'k', 'k', 'k', 'z', 'z', 'z', 'z', 'z', 'c', 'p', 'p', 'p'] 
>>> 
+0

Разве вы не переопределяете себя: кто говорит, что объекты 'str' будут поданы: спецификации только говорят что-то около нуля. Кроме того, подход не является динамическим, поскольку незначительные изменения в спецификациях могут привести к другому методу. –

+0

Я так не думаю. Он сказал, что хочет преобразовать каждый кусок целых чисел в последний известный _character_. Он сказал, что персонаж, поэтому я это и проверял мой код; характер". –

+0

где вы это читаете? Единственным буквальным обозначением OP является '0'. –