I am trying to remove items from a list as long as they contain any numeric characters in them. The code I have works, at least it detects them, but at the time of deleting it leaves me one of them, could you tell me my mistake? Thanks in advance
a=["symbol","ETHB3TC","price","0.06715900","s1ymbol","LTCBTC","price","0.00266700"]
def has_numbers(inputString):
return any(char.isdigit() for char in inputString)
for i in a:
eck=has_numbers(i)
print(eck)
If I run it like this, it detects all the elements with numbers without any problem
exit:
False
True
False
True
True
False
False
True
but if I tell it to remove the items, it doesn't remove all of them:
for i in a:
eck=has_numbers(i)
if eck:
a.remove(i)
print(a)
exit:
['symbol', 'price', 's1ymbol', 'LTCBTC', 'price']
I don't understand why 's1ymbol' doesn't remove me, what breaks my brain the most is that I repeat the for loop if it removes it
EDIT: the answer to my question is below, but if you don't want to create a new list you can work in reverse and with the indexes like this:
for i in range(len(a)-1,-1,-1):
eck=has_numbers(a[i])
if eck:
del a[i]
As a general rule, never modify what you are iterating over, be it a list or another container.
The standard pattern for altering a list while traversing it is to create a second list with the elements selected from the first.
That said, the implementation is
When finished, it
lista
contains the desired elements.This has a minimal effect on memory consumption, as the elements themselves are not duplicated. The new list (same as the original) only contains the references to those elements ( pointers ).
show
produces:
I'll explain @Nigan, when you eliminate the elements of a list that you are iterating, the indices move, example:
iteration 1:
iteration 2:
itertion 3:
As you can see it is not "price" because its position was modified and "0.06715900" took its place.
iteration 4:
** As you can see it is not "s1ymbol" since "LTCBTC" took its position
iteration 5:
iteration 6:
The final result is the following list:
This is why a list that is iterated is not modified, a new one is created to store the values you need
My solution is to create a copy of the list and remove the items from the copy
Very briefly:
In a for loop, if you add or remove elements from a list during its execution, the "internal counter" of the loop is affected, causing the next iteration to skip the next element that was defaulted if you did not modify anything.
For this type of case, it is best to start at the end of the list and work your way down.