简体   繁体   中英

Passing a parameter through a python filter function

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.

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]

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]

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

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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM