Reputation: 300
I'm trying to remove elements of a list if they can be found somewhere in a string.
But somehow, the final list contains elements that surely are not in the string.
Can someone point me in the right direction? Not sure if it's because the list is being altered during the loop or something like that.
Here's my code:
big_string = '209301293012931234847123'
small_strings = ['1', '2', 'sugar', 'juice', '666']
for element in small_strings:
if element not in big_string:
small_strings.remove(element)
print(small_strings)
The output I expected is:
['1', '2']
Instead what I get is:
['1', '2', 'juice']
Note: If I make a copy of the list and modify only that list (using the other one as reference) it seems to work perfectly. Why is that? Is there another way to do it, besides creating a copy?
Upvotes: 0
Views: 56
Reputation: 6237
You are getting unexpected results because you are altering the list inside the for loop. The easiest way of doing what you want is to make a copy of the list. However, if you absolutely have to edit the list in place, you can use a while loop.
big_string = '209301293012931234847123'
small_strings = ['1', '2', 'sugar', 'juice', '666']
current_index = len(small_strings) - 1
while current_index >= 0:
element = small_strings[current_index]
if element not in big_string:
small_strings.pop(current_index)
current_index -= 1
print(small_strings)
This code loops backwards over the list, as pop() has better performance when removing elements near the end of the list. However, making a copy of the list may well be faster than using a while loop, if you can spare the extra memory. (Although as with all things performance-related, you should measure before you optimise anything.)
Upvotes: 1
Reputation: 522741
We can try using a list comprehension here:
small_strings_out = [x for x in small_strings if x not in big_string]
print(small_strings_out)
This prints:
['sugar', 'juice', '666']
Upvotes: 1