Удалить элементы из списка, которые находятся непосредственно перед определенным элементом

Допустим у меня есть список:

a = ['no', 'no', 'no', 'yes', 'no', 'yes', 'no']

здесь я хочу удалить все 'no' которому предшествует каждый 'yes'. Так что мой окончательный список должен быть как:

['no', 'no', 'yes', 'yes', 'no']

я обнаружил, что для удаления элемента из списка по его значению мы можем использовать list.remove(..) as:

a = ['no', 'no', 'no', 'yes', 'no', 'yes', 'no']
a.remove('no')
print a

но это дает мне результат только с удалением первого появления 'no' as:

['no', 'no', 'yes', 'no', 'yes', 'no']

как я могу достичь желаемого результата, удалив все вхождения 'no' которым предшествуют все 'yes' в моем списке?

5 ответов


попробуйте это:

a = ['no', 'no', 'no', 'yes', 'no', 'yes', 'no']
a = ' '.join(a)  
print(a.replace('no yes', 'yes').split(' '))

что он делает: 1. объединение списка в строку с помощью ' '.join() 2. замена всех вхождений "нет да" на " да " на a.replace() 3. разбив его на список с помощью a.split(' ')


для удаления всех случаев 'no' которые присутствуют перед 'yes' в вашем списке вы можете использовать понимание С itertools.zip_longest(...) в Python 3.x (что эквивалентно iterools.izip_longest(..) в Python 2.x)(имея по умолчанию fillvalue as None) для достижения этого как:

>>> a = ['no', 'no', 'no', 'yes', 'no', 'yes', 'no']

# Python 3.x solution
>>> from itertools import zip_longest
>>> [x for x, y in zip_longest(a, a[1:]) if not(x=='no' and y=='yes')]
['no', 'no', 'yes', 'yes', 'no']

# Python 2.x solution
>>> from itertools import izip_longest
>>> [x for x, y in izip_longest(a, a[1:]) if not(x=='no' and y=='yes')]
['no', 'no', 'yes', 'yes', 'no']

возможно, Вам будет интересно взглянуть на zip_longest документ он говорит:

создайте итератор, который агрегирует элементы из каждой итерации. Если итераторы имеют неровную длину, недостающие значения заполняются с fillvalue. Итерация продолжается до тех пор, пока не будет исчерпана самая длинная итерация.


выполнить итерацию с условием и добавить последний элемент:

[i for i, j in zip(a, a[1:]) if (i == 'yes' or j == 'no')] + a[-1:]

интересный окольный путь, используя regex С look-ahead:

>>> import re
>>> s = ' '.join(a)                          # convert it into string
>>> out = re.sub('no (?=yes)', '', s)        # remove
>>> out.split()                              # get back the list
=> ['no', 'no', 'yes', 'yes', 'no']

попробуйте этот код !

Я также приложил скриншот вывода!

a = ['no', 'no', 'no', 'yes', 'no', 'yes', 'no']
for i in range (1,5):
  if a[i]=='yes':
    j=i-1
    a.pop(j)

print(a)

вывод:

enter image description here