Reputation: 1360
I'm trying to filter a list of words/phrases by some keyword. All the examples I've found of the filter()
function have been using numbers, so I'm wondering if this is even possible. I know that filter()
will put an item into the resulting list if the function it calls returns True
.
Let's say I have something like this:
def filtCheck(item, filt):
if filt in item:
return True
def funct():
filt = 'Hi'
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = filter(filtCheck(filt), set1)
print set2
Here is where I get confused. How exactly would I write that first parameter on the set2 line? Obviously not the way its written since my filtCheck function takes two parameters and I only provide one. Do I need to modify my filtCheck function too? But if I take the item parameter out of it, there's no string to check if filt is in.
Upvotes: 5
Views: 3217
Reputation: 21873
Keeping the construction of the example and taking a safe way, we need to pass an additional parameter with a default value:
def funct():
filt = 'Hi'
def filtCheck(item, filt=filt):
if filt in item:
return True
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = list(filter(filtCheck, set1))
print(set2)
Upvotes: 0
Reputation: 1381
The most direct modification to this code would be to have filtCheck return a function rather than a boolean value:
def filtCheck(value):
def is_in_list(lst):
return value in lst
return is_in_list
For your purposes, the function
argument for filter
is any function that takes exactly one parameter and returns a boolean value indicating whether or not it should be included in the result.
However, from the filter docs (http://docs.python.org/2/library/functions.html#filter),
Note that filter(function, iterable) is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.
Combining this equivalency with the fact that filter
is deprecated in python3, I would suggest you use list comprehensions:
def filtCheck(item, filt):
if filt in item:
return True
set2 = [item for item in set1 if filtCheck(filt, item)]
This can be further simplified to get rid of the need to use filtCheck
altogether:
def funct():
filt = 'Hi'
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = [item for item in set1 if filt in item]
print set2
Upvotes: 1
Reputation: 2147
You could use currying:
def filtCheck(filt):
return lambda item: filt in item
def funct():
filt = 'Hi'
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = filter(filtCheck(filt), set1)
print set2
Upvotes: 1
Reputation: 142256
Easier to switch to a list-comp:
filt = 'Hi'
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = [greeting for greeting in set1 if filt in greeting]
Upvotes: 1
Reputation: 100904
You could use a lambda (see also http://docs.python.org/2/reference/expressions.html#lambda):
set2 = filter(lambda item: filtCheck(item, 'Hi'), set1)
Or you could use functools.partial
:
from functools import partial
set2 = filter(partial(filtCheck, filt="Hi"), set1)
Or you could skip the filter function and use a list comprehension:
set2 = [item for item in set1 if filtCheck(item, "Hi")]
# or simply
set2 = [item for item in set1 if "Hi" in item]
Upvotes: 7