0

Why isn't the number 4 removed from the following list?

>>> list=[1,2,3,4]
>>> [list.remove(item) for item in list if item > 2]
[None]
>>> list
[1, 2, 4]

Also, what I'm trying to do is remove items from listA if item found in listB. How can I do this with list a comprehension?

Also, how would I do:

list2=["prefix1","prefix2"]
[item for item in list if not "item starts with a prefix in list2"] # pseudocode
timgeb
  • 76,762
  • 20
  • 123
  • 145
user3388884
  • 4,748
  • 9
  • 25
  • 34
  • 2
    Because deleting elements of the object when you are iterating over it makes the index to move, skipping the next value. So here is never evaluated. That's why it is important to make a copy before a loop and then replace the object. – llrs Jun 23 '14 at 15:06
  • 1
    What's `items` anyway? – vaultah Jun 23 '14 at 15:06
  • possible duplicate of [Remove items from a list while iterating in Python](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating-in-python) – Bill Lynch Jun 23 '14 at 15:08

1 Answers1

4

First of all, using a list comprehension only for its side effects is a bad practice. You should use

lst = [x for x in lst if x <= 2]

Additionally, don't use list as a variable name, because it is already taken by the builtin list. Third of all, your approach is not working because you are iterating over your list while mutating it.

Here's a demo of what's happening with your approach:

# python interpreter
>>> lst = [1,2,3,4]
>>> for item in lst:
...     print(item)
...     if item > 2:
...         lst.remove(item)
...     print(lst)
... 
1
[1, 2, 3, 4]
2
[1, 2, 3, 4]
3
[1, 2, 4]

As you can see, item is never 4.

As for your second question:

Also, what I'm trying to do is remove items from listA if item found in listB. How can I do this with list comprehension?

bset = set(listB)
listA = [x for x in listA if x not in bset]

As for your third question:

>>> list1=['prefix1hello', 'foo', 'prefix2hello', 'hello']
>>> prefixes=['prefix1', 'prefix2']
>>> [x for x in list1 if not any(x.startswith(prefix) for prefix in prefixes)]
['foo', 'hello']

Please stop adding new questions now, you can open a new question for a different problem, thanks.

timgeb
  • 76,762
  • 20
  • 123
  • 145