将set {1}作为参数传递时%timeit的特殊错误

时间:2017-11-21 10:53:18

标签: python jupyter-notebook jupyter

我遇到了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})有效。

为什么会这样?

1 个答案:

答案 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(Errors)
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)