python - 为什么从过滤器创建集合比创建列表或元组快得多?

标签 python python-3.x python-internals

我正在一个可互操作的对象上运行 filter 并希望将结果存储在一个序列中(我需要一个序列以便我可以在其上使用 random.choice) .我注意到从 filter 对象创建 set 比创建 listtuple 快得多。这是为什么?我首先虽然 filter 类型是 set 的子类型,这可以解释这一点,但 filter 函数实际上与生成器表达式相同,因此它不能真正是内部集合。

我运行了以下测试来检查速度:

import time

def test ( n, seq ):
    for method in ( set, list, tuple ):
        t = time.time()
        for i in range( n ):
            method( seq )
        print( method.__name__, ( time.time() - t ) )

someFilter = filter( lambda x: x % 3 == 0, range( 1000 ) )
test( 10000000, someFilter )

使用集合的结果很清楚:

set 1.9240000247955322
list 8.82200002670288
tuple 7.031999826431274

那么为什么从过滤器创建集合要快得多?它通常不应该像从一个序列创建一个集合一样长,其中每个元素都必须被散列吗?或者它是否以某种方式从内部过滤器表示中得到提升?

为了比较,当在 range 表达式上运行测试时,set 花费的时间大约是 listtuple< 的两倍(两者的速度几乎相同)。

编辑:

Sven 的回答完全正确,但为了完整起见,更新后的测试将在实际过滤器上运行:

import time

def testFilter ( n, test, rangeSize ):
    for method in ( set, list, tuple ):
        t = time.time()
        for i in range( n ):
            method( filter( test, range( rangeSize ) ) )
        print( method.__name__, ( time.time() - t ) )

testFilter( 100000, lambda x: x % 3 == 0, 1000 )

结果实际上显示了 listtuple 都是最快的,虽然 set 并不是真的慢,所以它不会有任何区别使用什么:

set 27.868000030517578
list 27.131999969482422
tuple 27.138000011444092

最佳答案

filter() 在 Python 3 中返回一个迭代器,这个迭代器将在内部 for 循环的第一次运行时被消耗。之后,您只是在衡量构造函数的速度——这就是为什么您必须如此频繁地重复它以使其至少消耗一点时间。

所以看来 set() 的构造函数是处理空迭代器最快的。

关于python - 为什么从过滤器创建集合比创建列表或元组快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8087761/

相关文章:

python - 如何按照 python 中 matplotlib 中收到的顺序对条形进行排序?

python - 根据 Django 模型中的条件根据需要创建模型字段

python - Python 2 使用什么方法打印元组?

Python:名称评估如何在运行时执行

python - 在不保存图像的情况下使用 matplotlib 时删除图像周围的白色边框

python - 使用 ElementTree 强制对不良 XML 文件进行编码

python - 使用 Bokeh 散点函数的对数刻度

python - 从代码中获取所有硬编码路径,如何处理配置文件?

python-3.x - 可以将我的临时文件放入我的应用程序中的 tmp/目录吗?

python - Python 的 reversed() 函数是如何工作的?