filter
, map
, and reduce
work perfectly in Python 2. Here is an example:
在Python 2中,可以完美地过滤、映射和减少工作。这是一个例子:
>>> 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
But in Python 3, I receive the following outputs:
但是在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
I would appreciate if someone could explain to me why this is.
如果有人能解释一下为什么会这样,我将不胜感激。
Screenshot of code for further clarity:
代码的屏幕截图进一步清晰:
3 个解决方案
#1
241
You can read about the changes in What's New In Python 3.0. You should read it thoroughly when you move from 2.x to 3.x since a lot has been changed.
您可以阅读Python 3.0中的新内容的更改。当你从2开始的时候,你应该仔细阅读它。x 3。因为很多东西都变了。
The whole answer here are quotes from the documentation.
这里的全部答案是来自文档的引用。
Views And Iterators Instead Of Lists
视图和迭代器而不是列表
Some well-known APIs no longer return lists:
一些著名的api不再返回列表:
- [...]
- […]
map()
andfilter()
return iterators. If you really need a list, a quick fix is e.g.list(map(...))
, but a better fix is often to use a list comprehension (especially when the original code uses lambda), or rewriting the code so it doesn’t need a list at all. Particularly tricky ismap()
invoked for the side effects of the function; the correct transformation is to use a regularfor
loop (since creating a list would just be wasteful).- map()和filter()返回迭代器。如果您确实需要一个列表,那么一个快速修复就是list(map(…)),但是更好的解决方法通常是使用列表理解(特别是当原始代码使用lambda),或者重写代码,这样它就不需要列表了。特别棘手的是针对函数的副作用调用map();正确的转换是使用一个常规的for循环(因为创建一个列表将是浪费)。
- [...]
- […]
内置命令
- [...]
- […]
- Removed
reduce()
. Usefunctools.reduce()
if you really need it; however, 99 percent of the time an explicitfor
loop is more readable.- 减少()删除。如果确实需要,可以使用function .reduce();然而,99%的情况下,一个显式的for循环更加可读。
- [...]
- […]
#2
62
The functionality of map
and filter
was intentionally changed to return iterators, and reduce was removed from being a built-in and placed in functools.reduce
.
map和filter的功能被有意地更改为返回迭代器,并且reduce被从内置的功能中删除,并放置到function tools.reduce中。
So, for filter
and map
, you can wrap them with list()
to see the results like you did before.
因此,对于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
>>>
The recommendation now is that you replace your usage of map and filter with generators expressions or list comprehensions. Example:
现在的建议是使用生成器表达式或列表理解替换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]
>>>
They say that for loops are 99 percent of the time easier to read than reduce, but I'd just stick with functools.reduce
.
他们说for循环有99%的时间更容易阅读而不是减少,但我还是坚持使用function工具。
Edit: The 99 percent figure is pulled directly from the What’s New In Python 3.0 page authored by Guido van Rossum.
编辑:99%的数字直接来自于由Guido van Rossum撰写的Python 3.0页面的新内容。
#3
5
As an addendum to the other answers, this sounds like a fine use-case for a context manager that will re-map the names of these functions to ones which return a list and introduce reduce
in the global namespace.
作为对其他答案的补充,这听起来像是上下文管理器的一个很好的用例,它将这些函数的名称重新映射到返回列表并在全局名称空间中引入reduce的函数。
A quick implementation might look like this:
一个快速实现可能是这样的:
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 a usage that looks like this:
其用法如下:
with noiters(map):
from operator import add
print(reduce(add, range(1, 20)))
print(map(int, ['1', '2']))
Which prints:
打印:
190
[1, 2]
Just my 2 cents :-)
就我的2分:-)
#1
241
You can read about the changes in What's New In Python 3.0. You should read it thoroughly when you move from 2.x to 3.x since a lot has been changed.
您可以阅读Python 3.0中的新内容的更改。当你从2开始的时候,你应该仔细阅读它。x 3。因为很多东西都变了。
The whole answer here are quotes from the documentation.
这里的全部答案是来自文档的引用。
Views And Iterators Instead Of Lists
视图和迭代器而不是列表
Some well-known APIs no longer return lists:
一些著名的api不再返回列表:
- [...]
- […]
map()
andfilter()
return iterators. If you really need a list, a quick fix is e.g.list(map(...))
, but a better fix is often to use a list comprehension (especially when the original code uses lambda), or rewriting the code so it doesn’t need a list at all. Particularly tricky ismap()
invoked for the side effects of the function; the correct transformation is to use a regularfor
loop (since creating a list would just be wasteful).- map()和filter()返回迭代器。如果您确实需要一个列表,那么一个快速修复就是list(map(…)),但是更好的解决方法通常是使用列表理解(特别是当原始代码使用lambda),或者重写代码,这样它就不需要列表了。特别棘手的是针对函数的副作用调用map();正确的转换是使用一个常规的for循环(因为创建一个列表将是浪费)。
- [...]
- […]
内置命令
- [...]
- […]
- Removed
reduce()
. Usefunctools.reduce()
if you really need it; however, 99 percent of the time an explicitfor
loop is more readable.- 减少()删除。如果确实需要,可以使用function .reduce();然而,99%的情况下,一个显式的for循环更加可读。
- [...]
- […]
#2
62
The functionality of map
and filter
was intentionally changed to return iterators, and reduce was removed from being a built-in and placed in functools.reduce
.
map和filter的功能被有意地更改为返回迭代器,并且reduce被从内置的功能中删除,并放置到function tools.reduce中。
So, for filter
and map
, you can wrap them with list()
to see the results like you did before.
因此,对于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
>>>
The recommendation now is that you replace your usage of map and filter with generators expressions or list comprehensions. Example:
现在的建议是使用生成器表达式或列表理解替换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]
>>>
They say that for loops are 99 percent of the time easier to read than reduce, but I'd just stick with functools.reduce
.
他们说for循环有99%的时间更容易阅读而不是减少,但我还是坚持使用function工具。
Edit: The 99 percent figure is pulled directly from the What’s New In Python 3.0 page authored by Guido van Rossum.
编辑:99%的数字直接来自于由Guido van Rossum撰写的Python 3.0页面的新内容。
#3
5
As an addendum to the other answers, this sounds like a fine use-case for a context manager that will re-map the names of these functions to ones which return a list and introduce reduce
in the global namespace.
作为对其他答案的补充,这听起来像是上下文管理器的一个很好的用例,它将这些函数的名称重新映射到返回列表并在全局名称空间中引入reduce的函数。
A quick implementation might look like this:
一个快速实现可能是这样的:
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 a usage that looks like this:
其用法如下:
with noiters(map):
from operator import add
print(reduce(add, range(1, 20)))
print(map(int, ['1', '2']))
Which prints:
打印:
190
[1, 2]
Just my 2 cents :-)
就我的2分:-)