如何在Python3中使用filter、map和reduce

如何在Python3中使用filter、map和reduce,python,python-3.x,filter,functional-programming,reduce,Python,Python 3.x,Filter,Functional Programming,Reduce,filter、map和reduce在Python2中工作得非常好。以下是一个例子: >>> def f(x): return x % 2 != 0 and x % 3 != 0 >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] >>> def cube(x): return x*x*x >>> map(cube, range(1,

filter
map
reduce
在Python2中工作得非常好。以下是一个例子:

>>> def f(x):
        return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

>>> def cube(x):
        return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

>>> def add(x,y):
        return x+y
>>> reduce(add, range(1, 11))
55
但在Python 3中,我收到以下输出:

>>> filter(f, range(2, 25))
<filter object at 0x0000000002C14908>

>>> map(cube, range(1, 11))
<map object at 0x0000000002C82B70>

>>> reduce(add, range(1, 11))
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    reduce(add, range(1, 11))
NameError: name 'reduce' is not defined
过滤器(f,范围(2,25)) >>>地图(立方体,范围(1,11)) >>>减少(增加,范围(1,11)) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 减少(增加,范围(1,11)) NameError:未定义名称“reduce” 如果有人能向我解释这是为什么,我将不胜感激

为进一步清晰起见,代码截图:


故意将
map
filter
的功能更改为返回迭代器,并将reduce从内置功能中删除并放置在
functools.reduce中

因此,对于
filter
map
,您可以使用
list()
包装它们,以便像以前一样查看结果

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> list(filter(f, range(2, 25)))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> list(map(cube, range(1, 11)))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> import functools
>>> def add(x,y): return x+y
...
>>> functools.reduce(add, range(1, 11))
55
>>>
现在建议您使用生成器表达式或列表理解替换map和filter。例如:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> [i for i in range(2, 25) if f(i)]
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> [cube(i) for i in range(1, 11)]
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>>
他们说for循环99%的时间比reduce更容易阅读,但我还是坚持使用
functools.reduce


编辑:99%的数字直接从Guido van Rossum编写的页面中提取。

故意将
映射
过滤器
的功能更改为返回迭代器,并将reduce从内置功能中删除并放置在
functools.reduce中

因此,对于
filter
map
,您可以使用
list()
包装它们,以便像以前一样查看结果

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> list(filter(f, range(2, 25)))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> list(map(cube, range(1, 11)))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> import functools
>>> def add(x,y): return x+y
...
>>> functools.reduce(add, range(1, 11))
55
>>>
现在建议您使用生成器表达式或列表理解替换map和filter。例如:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> [i for i in range(2, 25) if f(i)]
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> [cube(i) for i in range(1, 11)]
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>>
他们说for循环99%的时间比reduce更容易阅读,但我还是坚持使用
functools.reduce


编辑:99%的数据是直接从Guido van Rossum编写的页面中提取出来的。

您可以阅读有关数据变化的信息。当你从2.x移动到3.x时,你应该仔细阅读它,因为很多东西已经改变了

这里的全部答案都引用了文档

一些著名的API不再返回列表:

  • [……]
  • 并返回迭代器。如果你真的需要一个列表,一个快速修复方法是,例如,
    list(map(…))
    ,但更好的修复方法通常是使用列表理解(特别是当原始代码使用lambda时),或者重写代码,使其根本不需要列表。特别棘手的是
    map()
    调用函数的副作用;正确的转换是使用常规的
    for
    循环(因为创建列表只会浪费时间)
  • [……]

  • [……]
  • 已删除
    reduce()
    。如果你真的需要,就用它;但是,99%的时候,显式
    for
    循环更具可读性
  • [……]

您可以阅读中的更改。当你从2.x移动到3.x时,你应该仔细阅读它,因为很多东西已经改变了

这里的全部答案都引用了文档

一些著名的API不再返回列表:

  • [……]
  • 并返回迭代器。如果你真的需要一个列表,一个快速修复方法是,例如,
    list(map(…))
    ,但更好的修复方法通常是使用列表理解(特别是当原始代码使用lambda时),或者重写代码,使其根本不需要列表。特别棘手的是
    map()
    调用函数的副作用;正确的转换是使用常规的
    for
    循环(因为创建列表只会浪费时间)
  • [……]

  • [……]
  • 已删除
    reduce()
    。如果你真的需要,就用它;但是,99%的时候,显式
    for
    循环更具可读性
  • [……]

作为其他答案的补充,这听起来像是一个很好的上下文管理器用例,它将这些函数的名称重新映射到返回列表并在全局名称空间中引入
reduce

快速实现可能如下所示:

from contextlib import contextmanager    

@contextmanager
def noiters(*funcs):
    if not funcs: 
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func
with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))
其用法如下所示:

from contextlib import contextmanager    

@contextmanager
def noiters(*funcs):
    if not funcs: 
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func
with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))
其中打印:

190
[1, 2]

仅我的2美分:-)

作为其他答案的补充,这听起来像是一个很好的上下文管理器用例,它将这些函数的名称重新映射到返回列表的函数,并在全局名称空间中引入
reduce

快速实现可能如下所示:

from contextlib import contextmanager    

@contextmanager
def noiters(*funcs):
    if not funcs: 
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func
with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))
其用法如下所示:

from contextlib import contextmanager    

@contextmanager
def noiters(*funcs):
    if not funcs: 
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func
with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))
其中打印:

190
[1, 2]

只需我的2美分:-)

由于已从Python3的内置函数中删除了
reduce
方法,请不要忘记在代码中导入
functools
。请看下面的代码片段

import functools
my_list = [10,15,20,25,35]
sum_numbers = functools.reduce(lambda x ,y : x+y , my_list)
print(sum_numbers)

由于已从Python3的内置函数中删除了
reduce
方法,因此不要忘记在代码中导入
functools
。请看下面的代码片段

import functools
my_list = [10,15,20,25,35]
sum_numbers = functools.reduce(lambda x ,y : x+y , my_list)
print(sum_numbers)

下面是Filter、map和reduce函数的示例

数字=[10,11,12,22,34,43,54,34,67,87,88,98,99,87,44,66]

//滤器

oddNumbers=列表(筛选器(lambda x:x%2!=0,数字))

打印(奇数)

//地图

multiplyOf2=列表(映射(λx:x*2,数字))

打印(倍数f2)

//减少

由于reduce函数不常用,因此从Python 3中的内置函数中删除了它。它在functools模块中仍然可用,因此您可以执行以下操作:

从functools导入reduce

sumOfNumbers=减少(λx,y:x+y,数字)

打印(总数)