为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Python 3中使用过滤器、映射和精简

如何在Python 3中使用过滤器、映射和精简

眼眸繁星 2019-07-11 15:30:26
如何在Python 3中使用过滤器、映射和精简filter, map,和reduce在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但是在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如果有人能向我解释这是为什么,我将不胜感激。
查看完整描述

3 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

您可以在Python3.0的新特性是什么?..当你从2.x移到3.x时,你应该彻底阅读它,因为很多东西都变了。

这里的全部答案是引用文档的话。

视图和迭代器而不是列表

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

  • [...]

  • map()

    filter()

    返回迭代器。如果你真的需要一个清单,一个快速的解决办法是。

    list(map(...))

    但是更好的解决方法通常是使用列表理解(特别是当原始代码使用lambda时),或者重写代码,这样它就根本不需要列表了。特别棘手的是

    map()

    为函数的副作用调用;正确的转换是使用常规的

    for

    循环(因为创建一个列表只是浪费)。
  • [...]

内建

  • [...]

  • 移除

    reduce()

    ..使用

    functools.reduce()

    如果您真的需要它,但是99%的时间是显式的

    for

    循环更易读。
  • [...]


查看完整回答
反对 回复 2019-07-11
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

的功能map和filter被有意更改为返回迭代器,并从内置并放置在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]

>>>

他们说循环是99%的时间容易读比减少,但我只坚持functools.reduce.


99%的数字直接从Python3.0的新特性是什么?书名:Guido van Rossum.

查看完整回答
反对 回复 2019-07-11
?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

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

快速实现可能如下所示:

from contextlib import contextmanager    

@contextmanagerdef 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]

只是我的两分钱:-)


查看完整回答
反对 回复 2019-07-11
  • 3 回答
  • 0 关注
  • 567 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信