使用 timeit 时无法将列表传递给此 Python 函数

Unable to pass list to this Python function when using timeit

我写了一个小脚本来生成具有不同输入的函数的 运行 次。我的目的是绘制数字并向自己证明该函数确实具有二次 运行 时间。这是代码:

import timeit

seq = [875011, 549220, 400865, 913974, 699921, 108386, 328934, 593902, 805659, 916502, 597662]

subseq = []
num = 1000000 # How many times the algorithm must run

# Quadratic running time
def quad (S):
    n = len(S)
    A = [0] * n

    for j in range(n):
        total = 0
        for i in range(j+1):
            total += S[i]
        A[j] = total / (j+1)

    return A

def plot_func (name):
    print('\n')
    for i in range(len(seq)):
        subseq = seq[0:i+1]
        t = timeit.Timer('{}(subseq)'.format(name), 'from __main__ import {}, subseq'.format(name))
        print(t.timeit(number=num))

plot_func('quad')

问题是 运行 时间没有变化,那是因为每次运行时,函数 quad 引用全局 subseq,它是空的。如何将此子序列正确传递给此函数?

P.S.: 我也可以使用另一个工具来完成这项工作,只要它能给我准确的 运行 时间(根据 CPU 使用的时间) 函数的每次迭代。

默认情况下,Python 认为 subseq 是函数的局部变量。此本地名称隐藏了您将参数传递给 timeit 计时器的全局变量。

要进行赋值操作globally-visible,需要在函数中使用前将subseq变量声明为global

def plot_func (name):
    global subseq
    print('\n')
    for i in range(len(seq)):
        subseq = seq[0:i+1]

将您的代码与您要测量的代码分开通常不是一个好主意。
由于您的目标只是衡量您的算法以检查结果,我建议您 运行 timeit 范围内的所有内容,如下所示

import timeit

num = 1000000 # How many times the algorithm must run
setup = """
    seq = [875011, 549220, 400865, 913974, 699921, 108386, 328934, 593902, 805659, 916502, 597662]

    subseq = []

    # Quadratic running time
    def quad (S):
        n = len(S)
        A = [0] * n

        for j in range(n):
            total = 0
            for i in range(j+1):
                total += S[i]
            A[j] = total / (j+1)

        return A
    """
run_function = """
    def plot_func (name):
        print('\n')
        for i in range(len(seq)):
            subseq = seq[0:i+1]
            print(t.timeit(number=num))
    plot_func('quad')
"""
timeit.timeit(stmt=run_function, setup=setup, number=num)

这样,timeit 将在其范围内设置所有内容,运行 您定义的函数也会在其中设置。
重要的是要注意从 print 语句到 运行 所花费的时间也将被计算在内,但是,这不会显着改变结果,最重要的是,不会使其失去其二次上下文