How to select elements of a specific type in a list?
Question:
I am trying to write a function to select only the elements of my_list
that are of the type specified by type_elem
. Here is my code:
def filter_list(my_list, type_elem):
for elem in my_list:
if type_elem == int and isinstance(elem, str):
my_list.remove(elem)
return my_list
print(filter_list([35, True, 'abc', 10], int))
In this case output must be: [35, 10]
If it were str, for example, as a second argument, the output must be ['abc']
. And so on
Answers:
In your situation, you don’t actually care what type_elem
is: you only care about whether an element of the list is an instance of type_elem
. This can be checked by simply doing if isinstance(elem, type_elem)
.
Also, you should create a new list to which you add the elements you want, instead of removing from the one you are iterating over, since that can lead to problems.
Your function would become:
def filter_list(my_list, type_elem):
result = []
for elem in my_list:
if isinstance(elem, type_elem):
result.append(elem)
return result
Since you’re just building up the result
list in that loop, it can be replaced by a list comprehension:
def filter_list(my_list, type_elem):
return [elem for elem in my_list if isinstance(elem, type_elem)]
Now, calling the function with different type_elem
returns a list containing only the elements of that type:
>>> print(filter_list([35, True, 'abc', 10], int))
[35, True, 10]
>>> print(filter_list([35, True, 'abc', 10], str))
['abc']
>>> print(filter_list([35, True, 'abc', 10], bool))
[True]
Note that the boolean is returned when you ask for ints because a boolean is a special case of integers. To prevent this, we could change the isinstance(elem, type_elem)
to type(elem) == type_elem
, which checks that the types are equal and doesn’t evaluate to True
for derived classes (See https://stackoverflow.com/a/1549854/843953):
def filter_list(my_list, type_elem):
return [elem for elem in my_list if type(elem) == type_elem]
Now, we get the expected output:
>>> print(filter_list([35, True, 'abc', 10], int))
[35, 10]
>>> print(filter_list([35, True, 'abc', 10], str))
['abc']
>>> print(filter_list([35, True, 'abc', 10], bool))
[True]
Here the problem is you only remove elements if type_elem == int, so it will work for int but not for other types. Try this:
def filter_list(my_list, type_elem):
return [e for e in my_list if isinstance(e, type_elem)]
Take into account that bool type is also an integer type
I am trying to write a function to select only the elements of my_list
that are of the type specified by type_elem
. Here is my code:
def filter_list(my_list, type_elem):
for elem in my_list:
if type_elem == int and isinstance(elem, str):
my_list.remove(elem)
return my_list
print(filter_list([35, True, 'abc', 10], int))
In this case output must be: [35, 10]
If it were str, for example, as a second argument, the output must be ['abc']
. And so on
In your situation, you don’t actually care what type_elem
is: you only care about whether an element of the list is an instance of type_elem
. This can be checked by simply doing if isinstance(elem, type_elem)
.
Also, you should create a new list to which you add the elements you want, instead of removing from the one you are iterating over, since that can lead to problems.
Your function would become:
def filter_list(my_list, type_elem):
result = []
for elem in my_list:
if isinstance(elem, type_elem):
result.append(elem)
return result
Since you’re just building up the result
list in that loop, it can be replaced by a list comprehension:
def filter_list(my_list, type_elem):
return [elem for elem in my_list if isinstance(elem, type_elem)]
Now, calling the function with different type_elem
returns a list containing only the elements of that type:
>>> print(filter_list([35, True, 'abc', 10], int))
[35, True, 10]
>>> print(filter_list([35, True, 'abc', 10], str))
['abc']
>>> print(filter_list([35, True, 'abc', 10], bool))
[True]
Note that the boolean is returned when you ask for ints because a boolean is a special case of integers. To prevent this, we could change the isinstance(elem, type_elem)
to type(elem) == type_elem
, which checks that the types are equal and doesn’t evaluate to True
for derived classes (See https://stackoverflow.com/a/1549854/843953):
def filter_list(my_list, type_elem):
return [elem for elem in my_list if type(elem) == type_elem]
Now, we get the expected output:
>>> print(filter_list([35, True, 'abc', 10], int))
[35, 10]
>>> print(filter_list([35, True, 'abc', 10], str))
['abc']
>>> print(filter_list([35, True, 'abc', 10], bool))
[True]
Here the problem is you only remove elements if type_elem == int, so it will work for int but not for other types. Try this:
def filter_list(my_list, type_elem):
return [e for e in my_list if isinstance(e, type_elem)]
Take into account that bool type is also an integer type