通过 python 过滤器函数传递参数



我正在尝试按某个关键字过滤单词/短语列表。我找到的所有filter()函数的例子都使用了数字,所以我想知道这是否可能。我知道如果filter()调用的函数返回True,则会将项目放入结果列表中。

假设我有这样的东西:

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

这就是我感到困惑的地方。我将如何在 set2 行上确切地编写第一个参数?显然不是它的编写方式,因为我的 filtCheck 函数需要两个参数,而我只提供一个。我还需要修改我的过滤检查功能吗?但是,如果我从中取出 item 参数,则没有字符串可以检查 filt 是否在里面。

你可以使用 lambda(另见 http://docs.python.org/2/reference/expressions.html#lambda):

set2 = filter(lambda item: filtCheck(item, 'Hi'), set1)

或者您可以使用functools.partial

from functools import partial
set2 = filter(partial(filtCheck, filt="Hi"), set1)

或者,您可以跳过过滤器功能并使用列表推导:

set2 = [item for item in set1 if filtCheck(item, "Hi")]
# or simply
set2 = [item for item in set1 if "Hi" in item]

更容易切换到列表组合:

filt = 'Hi'
set1 = ['Hello, world', 'Hi there', 'Hi friend']
set2 = [greeting for greeting in set1 if filt in greeting]

你可以使用咖喱:

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

对此代码最直接的修改是让 filtCheck 返回一个函数而不是一个布尔值:

def filtCheck(value):
    def is_in_list(lst):
        return value in lst
    return is_in_list

就您的目的而言,filterfunction参数是只接受一个参数并返回一个布尔值的函数,该值指示它是否应包含在结果中。

但是,从筛选器文档 (http://docs.python.org/2/library/functions.html#filter),

请注意,filter(function, iterable) 等效于 [如果函数(item)中的项目for item if function(item)] 不是 None 和 [可迭代中的项的项 if 项] 如果函数为 None。

将这种等效性与 python3 中不推荐使用 filter 的事实相结合,我建议您使用列表推导:

def filtCheck(item, filt):
    if filt in item:
        return True
set2 = [item for item in set1 if filtCheck(filt, item)] 

这可以进一步简化,以完全摆脱使用filtCheck的需要:

def funct():
    filt = 'Hi'
    set1 = ['Hello, world', 'Hi there', 'Hi friend']
    set2 = [item for item in set1 if filt in item]
    print set2

保持示例的构造并采取安全的方式,我们需要传递一个具有默认值的附加参数:

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)

最新更新