alvas
alvas

Reputation: 121992

Removing an item from list matching a substring

How do I remove an element from a list if it matches a substring?

I have tried removing an element from a list using the pop() and enumerate method but seems like I'm missing a few contiguous items that needs to be removed:

sents = ['@$\tthis sentences needs to be removed', 'this doesnt',
     '@$\tthis sentences also needs to be removed',
     '@$\tthis sentences must be removed', 'this shouldnt',
     '# this needs to be removed', 'this isnt',
     '# this must', 'this musnt']

for i, j in enumerate(sents):
  if j[0:3] == "@$\t":
    sents.pop(i)
    continue
  if j[0] == "#":
    sents.pop(i)

for i in sents:
  print i

Output:

this doesnt
@$  this sentences must be removed
this shouldnt
this isnt
#this should
this musnt

Desired output:

this doesnt
this shouldnt
this isnt
this musnt

Upvotes: 34

Views: 69583

Answers (3)

mjgpy3
mjgpy3

Reputation: 8937

This should work:

[i for i in sents if not ('@$\t' in i or '#' in i)]

If you want only things that begin with those specified sentential use the str.startswith(stringOfInterest) method

[i for i in sents if i.startswith('#')]

Upvotes: 20

cod3monk3y
cod3monk3y

Reputation: 9843

Another technique using filter

filter( lambda s: not (s[0:3]=="@$\t" or s[0]=="#"), sents)

The problem with your orignal approach is when you're on list item i and determine it should be deleted, you remove it from the list, which slides the i+1 item into the i position. The next iteration of the loop you're at index i+1 but the item is actually i+2.

Make sense?

Upvotes: 15

D.Shawley
D.Shawley

Reputation: 59553

How about something simple like:

>>> [x for x in sents if not x.startswith('@$\t') and not x.startswith('#')]
['this doesnt', 'this shouldnt', 'this isnt', 'this musnt']

Upvotes: 48

Related Questions