如何在Python 3中使用过滤,映射和归约

本文翻译自:How to use filter, map, and reduce in Python 3

filter , map , and reduce work perfectly in Python 2. Here is an example: filtermapreduce可以在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: 代码的屏幕截图,以进一步阐明:

Python 2和3的IDLE会话并排


#1楼

参考:https://stackoom.com/question/Ve6e/如何在Python-中使用过滤-映射和归约


#2楼

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 . mapfilter的功能被有意地更改为返回迭代器,并且reduce不再是内置的,而是放置在functools.reduce

So, for filter and map , you can wrap them with list() to see the results like you did before. 因此,对于filtermap ,可以用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. 现在的建议是,用生成器表达式或列表推导替换map和filter的用法。 Example: 例:

>>> 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%的时间里都比减少容易阅读,但是我只是坚持使用functools.reduce

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楼

You can read about the changes in What's New In Python 3.0 . 您可以阅读Python 3.0的新增功能中的更改。 You should read it thoroughly when you move from 2.x to 3.x since a lot has been changed. 从2.x升级到3.x时,您应该仔细阅读该文档,因为已经做了很多更改。

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() and filter() return iterators. map()filter()返回迭代器。 If you really need a list, a quick fix is eg 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. 如果您确实需要列表,则快速修复方法是例如list(map(...)) ,但是更好的解决方法通常是使用列表理解(尤其是当原始代码使用lambda时),或者重写代码以使其不根本不需要列表。 Particularly tricky is map() invoked for the side effects of the function; 为函数的副作用调用map()尤其棘手; the correct transformation is to use a regular for loop (since creating a list would just be wasteful). 正确的转换是使用常规的for循环(因为创建列表将很浪费)。
  • [...] [...]

Builtins 内建

  • [...] [...]
  • Removed reduce() . 删除了reduce() Use functools.reduce() if you really need it; 如果确实需要,请使用functools.reduce() however, 99 percent of the time an explicit for loop is more readable. 但是,显式for循环在99%的时间中更具可读性。
  • [...] [...]

#4楼

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美分:-)


#5楼

Since the reduce method has been removed from the built in function from Python3, don't forget to import the functools in your code. 由于reduce方法已从Python3的内置函数中删除,因此不要忘记将functools导入代码中。 Please look at the code snippet below. 请查看下面的代码段。

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

#6楼

Here are the examples of Filter, map and reduce functions. 以下是Filter,map和reduce函数的示例。

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

//Filter //过滤

oddNumbers = list(filter(lambda x: x%2 != 0, numbers)) 奇数=列表(filter(lambda x:x%2!= 0,数字))

print(oddNumbers) 打印(奇数)

//Map //地图

multiplyOf2 = list(map(lambda x: x*2, numbers)) multipleOf2 = list(map(lambda x:x * 2,数字))

print(multiplyOf2) 打印(multiplyOf2)

//Reduce //降低

The reduce function, since it is not commonly used, was removed from the built-in functions in Python 3. It is still available in the functools module, so you can do: 由于不常用reduce函数,因此已从Python 3的内置函数中删除了它。functools模块中仍提供了reduce函数,因此您可以执行以下操作:

from functools import reduce 从functools进口减少

sumOfNumbers = reduce(lambda x,y: x+y, numbers) sumOfNumbers = reduce(lambda x,y:x + y,数字)

print(sumOfNumbers) 打印(sumOfNumbers)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值