Reputation: 22953
I created a function that took a list as a parameter and removed either a space or a number. Code below:
def cleaner(List, filter_out=' '):
if filter_out == ' ':
for i in List:
if i == ' ':
List.remove(' ')
if filter_out == 'int':
for i in List:
if type(i) == int:
List.remove(i)
I tested it using a list like so:
myList = ['h' ' ', 'g', 1, 2, 3, 4, 5, 'p']
print(cleaner(myList, filter_out='int'))
I expected to get ['h' ' ', 'g', 'p']
but instead printed out ['h ', 'g', 2, 4, 'p']
Why did it leave the 1
and 2
? I thought that it would filter out all numbers in the list.
Upvotes: 1
Views: 85
Reputation: 20336
Removing items from a list while iterating it results in bad consequences:
>>> nums = [1, 2, 3, 4]
>>> for x in nums:
... print x
... nums.remove(x)
...
1
3
You start at index 0. You print nums[0]
, 1
. You then remove it. The next index is 1
. Well, [nums[1]
is 3
because now the list is [2, 3, 4]
. You print that, and remove it. The list is now [2, 4]
, and you are at the third index. Since nums[2]
does not exist, the loop ends, skipping two numbers. What you should do is take advantage of the builtin functions:
myList = ...
myList = filter(lambda x: not isinstance(x, int), myList)
For the example of ' '
, it would be:
myList = ...
myList = filter(str.strip, myList)
or
myList = filter(lambda x: x != ' ', myList)
Note: The Python 3 filter()
function returns a filter
object, not a list. That makes it more efficient if you are just iterating, but if you truly need a list, you can use list(filter(...))
.
All of these make a copy of the list instead of doing their work in place. If you want it in place, use myList[:] = ...
instead of myList = ...
(in the filter()
line). Note that a Python 3 filter
object does not need to be converted to a list for this to work.
Upvotes: 4
Reputation: 2333
This would be a proper way to do it for medium sized lists
def cleaner(lst,filter_item = ' '):
if filter_item == ' ':
for i in list(lst):
if i == ' ':
lst.remove(' ')
elif filter_item == 'int':
for i in list(lst):
if type(i) == int:
lst.remove(i)
myList = ['h' ' ', 'g', 1, 2, 3, 4, 5, 'p']
cleaner(myList, 'int')
print(myList)
or a nicer way:
def cleaner(lst,filter_item = ' '):
retval = None
if filter_item == ' ':
retval = [i for i in lst if i != ' ']
elif filter_item == 'int':
retval = [i for i in lst if type(i) != int]
return retval
myList = ['h' ' ', 'g', 1, 2, 3, 4, 5, 'p']
a=cleaner(myList)
print(a)
#['h ', 'g', 1, 2, 3, 4, 5, 'p']
a=cleaner(myList,'int')
print(a)
#['h ', 'g', 'p']
Upvotes: 1