不同速度的生成器到列表转换

2024-09-29 23:20:37 发布

您现在位置:Python中文网/ 问答频道 /正文

问题

因此,我编写了一个python函数,它通过递归地生成嵌套列表的所有元素来展平列表。我提出了两个不同版本的生成器创建函数(不是100%相同)。你知道吗

以下是两个版本:

def iterflatten_v1(lst):
    for x in lst:
        if isinstance(x, (list, tuple)):
            yield from iterflatten_v1(x)
        else:
            yield x

def flatten_v1(lst):
    return list(iterflatten_v1(lst))

你知道吗

def iterflatten_v2(lst):
    for x in lst:
        try:
            yield from iterflatten_v2(x)
        except TypeError:
            yield x

def flatten_v2(lst):
    return list(iterflatten_v2(lst))

然后我用以下代码测试了这两个函数的速度(timing function):

import time

def timing(f, a, n):
    print(f.__name__)
    r = range(n)
    t1 = time.clock()
    for i in r:
        f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a); f(a)
    t2 = time.clock()
    print(round(t2-t1, 3))

nested = [1, 1, 1, [1, 1, [1, 1, 1, [1, 1, 1, 1, [1, 1, 1, 1], 1, 1], 1, 1], 1], 1]
data = [nested for i in range(1000)]

timing(iterflatten_v1, data, 1000)  # 0.003
timing(iterflatten_v2, data, 1000)  # 0.003
timing(flatten_v1, data, 10)  # 1.647
timing(flatten_v2, data, 10)  # 3.005

问题

为什么iterflatten_v1生成器的转换速度几乎是iterflatten_v2生成器转换速度的两倍,即使生成器函数具有相同的速度?你知道吗


Tags: 函数infordatatimedef速度list
1条回答
网友
1楼 · 发布于 2024-09-29 23:20:37

正如在注释中所说,异常处理比在这种情况下测试类型实例消耗更多的内存。你知道吗

不过,您对这两种情况都进行了计时,计时可能会因数据而异(如果数据仅包含整数,则会更频繁地出现异常,并且v2将比v1更慢)

请注意,如果您没有tuplelist的子级,您可以通过使用isinstance(检查基类)来获得50%的加速比,并检查确切的类型:

def iterflatten_v1(lst):
    for x in lst:
        if type(x) in (list, tuple):
            yield from iterflatten_v1(x)
        else:
            yield x

在我的机器上,isinstance版本得到1,5秒,这个版本不到1秒。你知道吗

(是的,我测试了isinstance(x,collections.Sequence),非常失望,因为它比测试2种类型还要慢)

相关问题 更多 >

    热门问题