Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove elements from list which are just before some specific element

Tags:

python

list

Let's say I am having a list as:

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

Here I want to remove every 'no' which is preceded by every 'yes'. So my resultant list should be like:

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

I've found that in order to remove an element from a list by its value, we may use list.remove(..) as:

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

But it gives me result with only removing first occurrence of 'no' as:

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

How can I achieve the desired result by removing all the occurrence of 'no' which are preceded by all 'yes' in my list?

like image 846
dgr379 Avatar asked Jan 20 '18 09:01

dgr379


People also ask

How do you remove an element from a list based on value?

The remove() method is one of the ways you can remove elements from a list in Python. The remove() method removes an item from a list by its value and not by its index number.

How do you remove all the occurrences of a particular element in a list?

Use the remove() Function to Remove All the Instances of an Element From a List in Python. The remove() function only removes the first occurrence of the element. If you want to remove all the occurrence of an element using the remove() function, you can use a loop either for loop or while loop.

What removes an item at a specific index in a list?

You can use the pop() method to remove specific elements of a list. pop() method takes the index value as a parameter and removes the element at the specified index. Therefore, a[2] contains 3 and pop() removes and returns the same as output. You can also use negative index values.


4 Answers

For removing all the occurrence of 'no' which are present just before the 'yes' in your list, you may use list comprehension with itertools.zip_longest(...) in Python 3.x (which is equivalent of iterools.izip_longest(..) in Python 2.x) (having default fillvalue as None) to achieve this as :

>>> 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']

You might be interested in taking a look at the zip_longest document which says:

Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted.

like image 99
Moinuddin Quadri Avatar answered Oct 19 '22 06:10

Moinuddin Quadri


Try this:

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

What it is doing is: 1. merging the list into a string with ' '.join() 2. replacing all the occurrencies of 'no yes' with 'yes' by a.replace() 3. splitting it back into a list with a.split(' ')

like image 42
pyThink Avatar answered Oct 19 '22 07:10

pyThink


Iterate with the condition and append last item:

[i for i, j in zip(a, a[1:]) if (i == 'yes' or j == 'no')] + a[-1:]
like image 20
grovina Avatar answered Oct 19 '22 06:10

grovina


An interestingly roundabout way, using regex with a 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']
like image 31
Kaushik NP Avatar answered Oct 19 '22 08:10

Kaushik NP