babeyh
babeyh

Reputation: 699

remove two successive element from list python

There is a problem with removing successive elements from a list. For example I have an list;

['aaaaa', '@someword', '@otherword','bbbb',...]

I want remove from list elements that has @ char.

a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in a:
    if '@' in word:
        print("found @ in word :" +word)
        a.remove(word)

The output is; (found only first element, skipped second one.)

found @ in word :@someword

if I add some value between this element;

a = ['aaaaa', '@someword', 'qqqq', '@otherword','bbbb']

It catch two of them;

found @ in word :@someword
found @ in word :@otherword

I debug the code, if there are succesive somewords which include @ char, remove function skip the second one, because of the changing of indices after removing process.

how can i remove these words?

Upvotes: 1

Views: 253

Answers (6)

user8408080
user8408080

Reputation: 2468

You should never change a list you are iterating through, but rather make a new one:

b = [word for word in a if not '@' in word]

Upvotes: 2

Steven Stip
Steven Stip

Reputation: 387

The actual problem here is that you are looping through a list that you are editing(removing/adding items). This means that when you remove item 2 while you're on the second item, you will then reach item 4 in the next iteration.

Solutions are to loop over a copy of the list, or to create a copy of the list and return that (with list comprehension for example)

A copy of the list can be created with word[:].

a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in a[:]:
    if '@' in word:
        print("found @ in word :" +word)
        a.remove(word)

Upvotes: 1

Felix
Felix

Reputation: 2668

You can use a list comprehension to filter out elements based on a condition:

>>> original = ['aaaaa', '@someword', '@otherword','bbbb']
>>> filtered = [item for item in original if '@' not in item]
>>> filtered
['aaaaa', 'bbbb']

Or replace them:

>>> replaced = [item if '@' not in item else '' for item in original]
>>> replaced
['aaaaa', '', '', 'bbbb']

See documentation for more info. Hope it helps!

Upvotes: 2

Tega Erekata
Tega Erekata

Reputation: 11

It's not advisable to mutate the element of a list while you're looping over it.

a = ['aaaaa', '@someword', '@otherword','bbbb'] 
for index,word in enumerate(a):
    print(index, word)
    if '@' in word:
        a.remove(word)
        print(a)

The output of this is

(0, 'aaaaa')
(1, '@someword')
['aaaaa', '@otherword', 'bbbb']
(2, 'bbbb')

From this you can see that '@someword' is deleted and the element at index 2 is no longer '@otherword' it is now 'bbbb'. Therefore '@otherword' can not be deleted.

The second example you gave works because when you delete '@someword' the element at index 2 becomes '@otherword' therefore it can be deleted on the next iteration.

(0, 'aaaaa')
(1, '@someword')
['aaaaa', 'qqqq', '@otherword', 'bbbb']
(2, '@otherword')
['aaaaa', 'qqqq', 'bbbb']

I'll advise you to create a new list and just store the elements that don't contain '@' in it

a = ['aaaaa', '@someword', 'qqqq', '@otherword','bbbb']
new_list = [i for i in a if '@' not in i]
print(new_list) # ['aaaaa', 'qqqq', 'bbbb']

Upvotes: 1

paras chauhan
paras chauhan

Reputation: 787

word = ['aaaaa', '@someword', '@otherword','bbbb']    
filtered = list(filter( lambda x : '@' not in x ,word))

another way is you can user filter

Upvotes: 2

Manoj Kumar Biroj
Manoj Kumar Biroj

Reputation: 323

you need to add the list 'a' into a list. The below code might help you

a = ['aaaaa', '@someword', '@otherword','bbbb']
for word in list(a):
    if '@' in word:
        print("found @ in word :" +word)
        a.remove(word)

Upvotes: 1

Related Questions