Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with this python list removal loop?

Tags:

python

loops

list

I have been up far too long tonight working on a long program. But I have hit a simple roadblock. Can any one tell me why this code is working the way it is?

I have two lists. I want list2 to only contain numbers that are not in list1. logically this seems like it should work. But it doest at all. Why?

list1 = [1,2,3,4,5,6,7,8]
list2 = [12,15,16,7,34,23,5,23,76,89,9,45,4]


for ch in list2:
    if ch in list1:
         list2.remove(ch)

return list2

somehow, this returns: [15, 7, 5, 23, 76, 9, 4]

Why?

and how can I accomplish what I need?

like image 338
tknickman Avatar asked Dec 06 '22 18:12

tknickman


2 Answers

When you modify a sequence you are iterating over, it will yield unexpected results. I'd do it this way, which takes advantage of fast set operations.

list2 = list(set(list2) - set(list1))

Whether this is faster or slower than using a list comprehension depends on the sizes of list1 and list2, and whether you can make one into a set as part of initialization rather than multiple times in a loop.

like image 184
Michael Hoffman Avatar answered Dec 25 '22 11:12

Michael Hoffman


Don't modify a list while iterating over it.

What you want can be directly expressed with list comprehension:

list2 = [ch for ch in list2 if ch not in list1]

It is more readable, and unlike solutions with sets it will not remove duplicates from list2 or change item order.

UPDATE: when list1 is big, creating a set from it will actually speed things up:

list2 = [ch for ch in list2 if ch not in set(list1)]
like image 32
hamstergene Avatar answered Dec 25 '22 10:12

hamstergene