如何用最自然的方式编写一个带有否定条件的filter
(过滤器)?
例如:
is_even= lambda x : x % 2 == 0
odd_numbers= filter( lambda x: not is_even(x), range(10) )
当然,你可以直接使用列表推导式 - 但这时你就不需要使用
filter
了。如果有人想知道,我是在尝试根据条件拆分列表时遇到这个问题的。
如何用最自然的方式编写一个带有否定条件的filter
(过滤器)?
例如:
is_even= lambda x : x % 2 == 0
odd_numbers= filter( lambda x: not is_even(x), range(10) )
filter
了。itertools
模块包括 ifilter() 和 ifilterfalse(),它们分别筛选函数返回为True
和False
的元素。
odd_numbers = ifilterfalse(is_even, range(10))
注意,在Python 2中,filter
和ifilter
之间存在差异:在这里,odd_numbers
将是一个迭代器,而filter()
会返回一个列表(请参阅itertools.ifilter Vs. filter Vs. list comprehensions)。如果您确实想要构建一个列表,那么您使用not
的示例似乎很好,假设您决定使用filter
- 列表推导可能更加“习惯用法”(List filtering: list comprehension vs. lambda + filter)。
在Python 3中,filter()构造一个迭代器,而不是列表,itertools.filterfalse()是补集。
ifilterfalse
而不是ireject
有什么见解吗? - wpcarro基于谓词进行拆分被称为partition
。我认为实现partition
作为一个单独的函数比为奇数和偶数重复其内部实现更符合惯用语法。Python 3的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
和tee
。因此,您的最高级代码应如下所示:odds, evens = partition(is_even, range(10))
)
是打字错误吗? - Bhargav Rao