在python中将float转换为int的有效方法是什么?

Sri*_*har 13 python int performance

我一直在使用n = int(n)转换floatint.

最近,我遇到了另一种做同样事情的方法:

n = n // 1

哪种方式最有效,为什么?

Mar*_*ers 17

用以下方法测试timeit:

$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.234 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.218 usec per loop
Run Code Online (Sandbox Code Playgroud)

因此,地板划分只是一个较小的速度.请注意,这些值非常接近,我不得不提高循环重复次数以消除我机器上的随机影响.即使计数如此之高,您也需要重复几次实验,以确定数字仍然变化多少,以及大多数时间出现的速度更快.

这是合乎逻辑的,因为int()需要全局查找和函数调用(因此推送和弹出状态):

>>> import dis
>>> def use_int(n):
...     return int(n)
... 
>>> def use_floordiv(n):
...     return n // 1
... 
>>> dis.dis(use_int)
  2           0 LOAD_GLOBAL              0 (int)
              3 LOAD_FAST                0 (n)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(use_floordiv)
  2           0 LOAD_FAST                0 (n)
              3 LOAD_CONST               1 (1)
              6 BINARY_FLOOR_DIVIDE 
              7 RETURN_VALUE        
Run Code Online (Sandbox Code Playgroud)

它的LOAD_GLOBALCALL_FUNCTION操作码比LOAD_CONSTBINARY_FLOOR_DIVIDE操作码慢; LOAD_CONST是一个简单的数组查找,LOAD_GLOBAL需要进行字典查找.

绑定int()到本地名称可以产生一点点差异,再次给它带来优势(因为它必须做的工作少于// 1地板划分):

$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.233 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345; int_=int' 'int_(n)'
10000000 loops, best of 3: 0.195 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.225 usec per loop
Run Code Online (Sandbox Code Playgroud)

同样,您需要使用1000万个循环来运行它,以便始终如一地查看差异.

也就是说,int(n)更加明确,除非你在一个时间关键的循环中这样做,int(n)否则在可读性方面胜出它n // 1.时间性差异太小,使不得不制定出什么样的认知成本// 1 确实在这里值得的.

  • 对于这样的微小计算和时间,结果可能会根据后台进程而倾斜.但似乎两者几乎同样有效,我会选择`int(n)`以提高可读性. (2认同)