Python map()和filter()的组合

Python map()和filter()的组合,python,Python,我刚刚有了一个非常有趣的想法:map()和filter()之间的组合使用生成器作为谓词,从中产生。简而言之,下面是代码: def map_filter(function, iterable): """convert and filter a sequence""" for i in iterable: yield from function(i) 现在,怎么办?基本上,这是上述两个功能的组合,其中包含了这两个功能。实际上,将附加参数传递到map()的可能性仍然缺

我刚刚有了一个非常有趣的想法:map()和filter()之间的组合使用生成器作为谓词,
中产生。简而言之,下面是代码:

def map_filter(function, iterable):
    """convert and filter a sequence"""
    for i in iterable:
        yield from function(i)
现在,怎么办?基本上,这是上述两个功能的组合,其中包含了这两个功能。实际上,将附加参数传递到
map()
的可能性仍然缺失,尽管这是IMHO的一个小细节,可以为此进行扩展。下面是一个比较,生成数字的平方:

def function(x):
    return x * x
res = map(function, range(0, 10))
print(list(res))

def function(x):
    yield x * x
res = map_filter(function, range(0, 10))
print(list(res))
下面是另一个,过滤奇数:

def function(x):
    return x % 2 == 1
res = filter(function, range(0, 10))
print(list(res))

def function(x):
    if x % 2 == 1:
        yield x
res = map_filter(function, range(0, 10))
print(list(res))
最后一个,结合上面两个:

def function1(x):
    return x * x
def function2(x):
    return x % 2 == 1
res = map(function1, filter(function2, range(0, 10)))
print(list(res))

def function(x):
    if x % 2 == 1:
        yield x * x
res = map_filter(function, range(0, 10))
print(list(res))
说明和问题:

  • 当然,第一个问题是,我是在重新发明轮子,还是这是对Python的一个有用的补充(例如在itertools中)
  • 这有什么问题或缺点吗?我看到的一个是稍微复杂一点的接口,但它似乎是一般序列操作的有用工具
  • map\u filter()
    需要一个生成器(带有
    yield
    ),所以我不能将
    lambda
    与它一起使用(可以吗?)。因此,对于非常小的筛选/映射函数,代码量会更大,但在其他情况下,您可能可以使用组合筛选/映射函数编写更简洁的代码
  • 最好的卖点之一是,不仅可以使用
    map\u filter()
    从序列中删除元素,还可以使用它注入其他元素
  • 我当然愿意接受任何建议或改进

您可以定义生成器表达式:

>>> values = range(0, 10)
>>> evens = (value for value in values if not value % 2)
>>> even_squares = (even * even for even in evens)
>>> list(even_squares)
[0, 4, 16, 36, 64]

可以定义生成器表达式:

>>> values = range(0, 10)
>>> evens = (value for value in values if not value % 2)
>>> even_squares = (even * even for even in evens)
>>> list(even_squares)
[0, 4, 16, 36, 64]


这通常被称为“平面地图”,因为它是平面和地图的组合。使用itertools,您通常会执行
链。from_iterable(map(whatever,whatever))
。请原谅我的无知:from
yield from
从生成器获取值,而不是简单的函数。否则,您可能只需执行
yield function(i)
生成器只是一个函数(使用
def…
创建),它使用
yield
而不是
return
,@Pynchia。只需在函数中返回即可
从map(function,iterable)中生成
在我看来,对于上一个示例,显式循环可以重写为:
res=(x*x表示范围(0,10)内的x,如果x%2)
这通常被称为“flatmap”,因为它是由展平和映射组成的。使用itertools,您通常会执行
链。from_iterable(map(whatever,whatever))
。请原谅我的无知:from
yield from
从生成器获取值,而不是简单的函数。否则,您可能只需执行
yield function(i)
生成器只是一个函数(使用
def…
创建),它使用
yield
而不是
return
,@Pynchia。只需在函数中返回即可
从map(function,iterable)中生成
在我看来,这是一个非常好的例子,你上一个例子的显式循环可以重写为:
res=(x*x表示x在范围(0,10)内,如果x%2)
这可以用
列表缩短((值*值表示范围(0,10)内的值,如果值%2==0))
我的意思是,您不需要两个生成器表达式,但这就是问题所在,如何组合多个筛选器和转换,而不是如何将其重写为一行。即使如此,您始终使用筛选器和映射,但从不使用筛选器和筛选器或映射和映射,因此每个筛选器和映射都可以使用一个生成器表达式完成,这不是关于一个班轮。这是一个例子,你可以做什么,而不必组合成一个班轮。如果您正在使用它,则可以按您喜欢的方式进行组合。这可以通过
列表((值*范围(0,10)中的值,如果值%2==0))来缩短。
我的意思是,您不需要两个生成器表达式,但这就是问题所在,如何组合多个过滤器和转换,而不是如何将其重写为一行。即使如此,您总是使用过滤器和映射,但从不使用过滤器和过滤器或映射和映射,因此每个过滤器和映射都可以使用一个生成器表达式来完成,这不是关于一个线性的。这是一个不必组合成一个线性的示例。如果你正在使用它,你可以随意组合。