我遇到了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})
作品。
为什么会发生?
ah,您正在击中Magics的边缘情况之一,$variable
和{variable}
是为了插入Python变量。也就是说,{foo}
将被str(foo)
的值所取代。这对于外壳执行很有用,例如%bash rm {myfile}
。要说服自己,请使用-n1 -r1
运行时间(仅运行一个循环-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({{3}})
{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({{3}})
234 ns ± 3.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
您可以在https://github.com/ipython/ipython上打开一个错误,我敢肯定,如果有足够的抱怨,我们可能会在某个时候改变行为;或至少记录它。它可能是由{3}
触发的,而不是{1,2}
触发的,因为{3}
像{foo}
一样是"括号 - 识别器 - 托架",但{1,2}
不是。
请注意,如果您完全理解此答案,则可以使用{k}
将选项传递给时间IT本身:
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)