当前位置: 首页 > 知识库问答 >
问题:

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

谭泳
2023-03-14

filtermap减少在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个答案

孔彭祖
2023-03-14

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

哪些打印:

190
[1, 2]

只是我的2美分:-)

商天逸
2023-03-14

mapfilter的功能被有意地更改为返回迭代器,减少被从内置中删除并放置在functools.reduce中。

因此,对于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
>>>

现在的建议是,用生成器表达式或列表理解替换映射和筛选器的使用。示例:

>>> 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%的数字直接来自Guido van Rossum编写的Python 3.0的新增内容页面。

卞云瀚
2023-03-14

您可以阅读Python3.0中新增内容的变化。当你从2开始移动时,你应该仔细阅读它。x到3。因为很多东西都改变了。

这里的全部答案是引用从留档。

视图和迭代器而不是列表

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

  • [……]

内置

  • [……]
 类似资料:
  • 我有一组从共享类型继承的域对象(即、)。子类型具有特定的属性(即、)。 此外,作为解析日志文件的结果,我有一个包含混合子类型的记录列表。 为了计算日志记录上的统计信息,我想只在匹配特定子类型的记录子集上应用数学函数,即只在s上应用数学函数。因此,我希望有一个特定子类型的过滤流。我知道可以使用以下方法将和应用到子类型 在流上多次应用这个filter&cast(特别是在对同一子类型进行多次不同计算时)

  • 我是spark的新手,当我在java api中使用spark的filter时,我得到了这个错误(如果collect()所有表都正确工作,我可以看到从Cassandra获得的所有数据。)我检查了master和workers版本相同,当应用程序在spark的web ui中启动时,我可以看到它,但是: 以及spark Version2.1.1、scala Version2.11、Java8和my pom

  • 我正在使用Python 3.2。1并且我无法导入模块。我使用可以工作,但我不能将它与的一起使用,如下所示: 我得到以下错误: 当我写时,它说

  • 我有一个简单的流如下: 但Intellij建议我: “filter()”和“map()”可以互换。检查信息:报告流API调用链可以简化。它允许在遍历集合时避免创建冗余的临时对象。例如 collection.stream()→collection.for每个() collection.stream()。 Intellij给出的例子很容易理解,但我不明白为什么它建议我使用。 我查看了的来源,但没有找到

  • 本文向大家介绍java 在Jetty9中使用HttpSessionListener和Filter,包括了java 在Jetty9中使用HttpSessionListener和Filter的使用技巧和注意事项,需要的朋友参考一下 java 在Jetty9中使用HttpSessionListener和Filter HttpSessionListener 当Session创建或销毁的时候被调用 示例代码