习惯上否定过滤器

时间:2015-01-09 18:30:29

标签: python filter functional-programming negation

filter写一个否定的最惯用的方法是什么?

示例:

is_even= lambda x : x % 2 == 0
odd_numbers= filter( lambda x: not is_even(x), range(10) )

当然,你可以使用列表推导 - 但是你无论如何都不需要使用filter

如果有人想知道,我在尝试split a list based on a condition

时偶然发现了这一点

2 个答案:

答案 0 :(得分:6)

itertools模块包括ifilter()ifilterfalse(),它们分别对函数返回TrueFalse的元素进行过滤。

odd_numbers = ifilterfalse(is_even, range(10))

请注意,在Python 2中,filterifilter之间存在差异:odd_numbers这里将是一个迭代器,而filter()会给出一个列表(请参阅{{ 3}})。如果您确实要构建列表,那么not的示例似乎没问题,假设您已开始使用filter - 列表推导可能更“惯用”(itertools.ifilter Vs. filter Vs. list comprehensions)。

在Python 3中,List filtering: list comprehension vs. lambda + filter构造一个迭代器,而不是一个列表,filter()是补充。

答案 1 :(得分:2)

基于谓词的拆分称为partition。我会发现将partition实现为一个单独的函数而不是专门针对奇数和偶数重复其内部结构更为惯用。 Python 3' s Itertools Recipes具有以下实现:

def partition(pred, iterable):
    'Use a predicate to partition entries into false entries and true entries'
    # partition(is_odd, range(10)) --> 0 2 4 6 8   and  1 3 5 7 9
    t1, t2 = tee(iterable)
    return filterfalse(pred, t1), filter(pred, t2)

它使用filterfalse(如@Lack所述)和该模块中定义的tee。所以你的最高级代码看起来像是:

odds, evens = partition(is_even, range(10))