【问题标题】:Python's filter functions arguments order [closed]Python的过滤器函数参数顺序[关闭]
【发布时间】:2015-12-22 16:44:39
【问题描述】:

Python 的 filter 和 itertools.ifilter 函数具有以下签名:

filter(function, iterable)
itertools.ifilter(predicate, iterable)

是否有任何理由将predicate 参数放在iterable 之前?在这种情况下,不能跳过predicate 参数来简化filter(bool, [0, 1, 0, 2]) 对filter([0, 1, 0, 2]) 的调用。第二个对我来说看起来更惯用。

【问题讨论】:

  • 第二个没有任何意义。过滤没有谓词的列表?那怎么行?请记住,显式优于隐式 (import this)。
  • @VincentSavard:奇怪的是,实际上有一个没有谓词的过滤定义行为。如果您将None 作为谓词传递,则其工作方式与传递bool 或lambda x: x 相同。
  • 可能是因为map、filter、reduce等函数都出自函数式编程的传统,所以filter的参数顺序就是从这些函数中提取的。对于 map 和 reduce,这个参数顺序更有意义,虽然我很同情你关于 filter 单独的论点。
  • 部分应用有意义:even_filter = functools.partial(itertools.ifilter, lambda x: x % 2 == 0); foo = even_filter(foo)
  • 此外,在函数世界中,您可以将filter 视为一个函数,它接受一个参数(过滤器函数)并返回一个 new 函数,该函数接受一个list 作为参数并返回过滤后的列表。柯里化模糊了filter(func, iterable) 和filter(func)(iterable) 之间的界限。

标签: python parameter-passing idioms


【解决方案1】:

这有助于理解filter 借用的范式。与其将filter 视为一个将函数和列表作为两个参数的函数,不如将其视为一个接受单个参数(谓词)的函数。返回值是一个 new 函数,它接受一个列表并返回一个新列表。从这个意义上说,filter 是一个函数(实际上是一个函子),它将一个函数“提升”到一个新的“类别”中。

例如,假设你有一个谓词is_even,它接受一个整数作为参数,如果参数是偶数则返回真,如果是奇数则返回假。那么filter(is_even) 可以被认为是返回一个函数,该函数接受一个整数的list 并返回一个布尔值的list,每个元素指示相应输入项的均匀性。您可以将该函数应用于列表,以便 filter(is_even)(list_of_ints) 与 Python 中的 filter(is_even, list_of_ints) 相同。这种将多参数函数分解为一系列单参数函数的方法称为currying。

filter 的类型签名反映了它的起源和 Python 缺乏内置的柯里化。您可以使用functools.partial 模拟这一点,它允许您通过从左到右为定义的参数提供参数来部分应用函数。

from functools import partial
x = partial(filter, is_even)  # lambda lst: filter(is_even, lst)
new_list = x(list_of_ints)
# or just new_list = partial(filter, is_even)(list_of_ints)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多