I am trying to filter strings from a list. The assignment is:
Create a function that takes a list of non-negative numbers and strings and return a new list without the strings.
This is my code:
def filter_list(lst):
intlist = []
while len(lst) > 0:
if isinstance(lst[0],int):
if lst[0] >= 0
intlist.append(lst[0])
lst.remove(lst[0])
else:
lst.remove(lst[0])
if isinstance(lst[0],str):
lst.remove(lst[0])
return (intlist)
It gives me an error, and it seems I get stuck in an infinite while loop, although I do not understand how, as I gradually remove items from the list, and the loop ends when the list is empty.
Syntax errors aside, your code appears to work. But this design is very questionable because remove is a linear operation (the entire list needs to be shifted forward to fill the gap vacated by element 0), bringing the overall complexity to O(n2) for an algorithm that should be O(n).
Multiple nested conditions can cause cognitive overload and should be avoided.
It also fails when there are negative numbers and/or non-str/int elements.
There's no reason to mutate the input list; the function should be non-idempotent, that is, always produce the same result when called multiple times with the same input.
Handling all these problems is basically automatic using a list comprehension:
>>> lst = [42, 15, "foo", "bar", 33, "baz"]
>>> [x for x in lst if isinstance(x, int)]
[42, 15, 33]
or if you anticipate other non-integer values, more robust may be:
>>> [x for x in lst if not isinstance(x, str)]
[42, 15, 33]
Having said that, I don't recommend writing type-oriented logic in Python, generally speaking. Combining types in a list and writing branches to handle each item differently depending on its type often indicates a design flaw, although I understand this may be a contrived exercise.
Additionally, now that we have a one-liner, there's no reason for this to be in a function. Calling the function filter_list only obfuscates the logic without offering a clear name, description or contract to the caller as to what exactly is being filtered. Best to inline the logic in the caller wherever it's used. If it must be kept as a function, consider a header like filter_by_type(lst, type_to_keep) and call with filter_by_type(lst, int).
If you have an entry in the list that's not an int or a str, it'll remain in the list, and you'll get stuck in an infinite loop. I'd do something like this.
In [5]: def filter_lst(lst):
...: return [x for x in lst if isinstance(x, int) and x >= 0]
...:
In [6]: filter_lst([1, -3, "idk", 6])
Out[6]: [1, 6]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With