Python的过滤函数参数顺序

时间:2015-12-22 16:44:39

标签: python parameter-passing idiomatic

Python的filteritertools.ifilter函数具有下一个签名:

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

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

1 个答案:

答案 0 :(得分:4)

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

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

filter的类型签名反映了它的起源和Python缺乏内置的currying。您可以使用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)