我遇到了timeit
魔法函数的奇怪行为。
def f(S):
for x in S:
pass
%timeit f({3})
提出TypeError: 'int' object is not iterable
。
这是%timeit f(set([3]))
作品,
并且
%timeit f({1,2})
有效。
为什么会这样?
答案 0 :(得分:0)
啊,你正在击中魔法的边缘情况之一,$variable
和{variable}
意在插入python变量。也就是说{foo}
将替换为str(foo)
的值。这对shell执行很有用,例如%bash rm {myfile}
。要说服自己,请使用-n1 -r1
运行timeit(仅运行一个循环-r1
,-n1
),然后打印S
:
In [1]: def f(S):
...: print(S)
...:
...: %timeit -r1 -n1 f({3})
3
92.6 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
哦,我们得到3
而不是{3}
....解决方案,加倍{}
:
In [2]: def f(S):
...: print(S)
...:
...: %timeit -r1 -n1 f(https://github.com/ipython/ipython)
{3}
25.9 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
好的!让我们修复你的例子:
In [3]: def f(S):
...: for x in S:
...: pass
...: %timeit f()
234 ns ± 3.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
你可以在{{3}}上打开一个错误,如果有足够的抱怨我们可能会在某个时候改变行为,我很确定已经有一个错误。或者至少记录下来。它可能由{3}
而不是{1,2}
触发,因为{3}
是" bracket-identifier-bracket"例如{foo}
,但{1,2}
不是。
请注意,如果您完全理解这个答案,{k}
可用于将选项传递给自己定时:
In [4]: r=1
...: n=2
...: %timeit -n{n} -r{r} 1+1
292 ns ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each)