0

When I run this code, it works, but for some reason it only removes the 'p' and 'h' strings and not the 'z' string. Why?

def filter_list(l):
    for item in l:
        if item == str(item):
            l.remove(item)
    return l
print(filter_list([1, 9, 3, 'p', 'z', 7, 'h']))

output:[1, 9, 3, 'z', 7]

Mythic-ctrl
  • 37
  • 1
  • 6
  • 3
    You are modifying the list while iterating over it, so when 'p' is removed, you are skipping over 'z'. This question is answered on SO already here: https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating – pink spikyhairman May 01 '20 at 20:22
  • 3
    Does this answer your question? [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) When removing items from a sequence while iterating the indexing gets messed up and items don't get *visited*. – wwii May 01 '20 at 20:22
  • To illustrate the behavior insert a number between `p` and 'z'. – PM 77-1 May 01 '20 at 20:23

4 Answers4

0

Since you are performing a remove, the next element that the list starts to iterate by is 7 and not 'z'

in your 4th iteration of the loop, you recognize 'p' to be a string. The index of 'p' is 3. Once you do a remove, the index of 'z' is now 3 and since your loop goes for the next time, it skips 'z' and goes straight to 7.

Try this experiment, if you replace 'z' with 'p', your loop wont delete 'p'. Your logic for checking if an element is a string or not is not wrong per say [ideally you should use isinstance(element, type)] but its your logic of removing the element that has caused this.

Abhishek Malik
  • 305
  • 4
  • 14
0

In below code I have created a temporary list that will have all the 'string'. Then loop through temporary list and removed string from main list.

def filter_list(l):
    temp=[]
    for items in l:
        if str == type(items):
            temp.append(items)

    for item_to_remove in temp:
        l.remove(item_to_remove)
    return(l)

print(filter_list([1, 9, 3, 'p', 'z', 7, 'h']))

output

[1, 9, 3, 7]
Rima
  • 1,447
  • 1
  • 6
  • 12
0
def filter_list(l):
    new_l =[]
    for i in l:
        if str(i).isdigit():
            new_l.append(i)
    return new_l 

It work for both int 1 and str "1"

Output :

>>> filter_list([1, 9, 3, 'p', 'z', 7, 'h'])
[1, 9, 3, 7]
>>> filter_list(["1", "9", "3", 'p', 'z', "7", 'h']
['1', '9', '3', '7']
0

Could do:

def filter_list(l):    
    return [i for i in l if type(i) is not str]

Output:

>>> filter_list(['e', 'f', 1, 'c', 2, 4])
[1, 2, 4]

Returns only integers after checking if l[i] is not a string

STerliakov
  • 4,983
  • 3
  • 15
  • 37
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – STerliakov Dec 26 '21 at 13:19