关于部门:在Python中使用’//’的原因是什么?

What is the reason for having '//' in Python?

本问题已经有最佳答案,请猛点这里访问。

我在别人的密码里看到了:

1
y = img_index // num_images

其中,img_index为运行指数,num_images为3。

当我在ipython中与//混在一起时,它看起来就像一个除法符号(即一个正斜杠)。我只是想知道是否有任何理由有双正斜杠?


在python 3中,他们让/操作符进行浮点除法,并添加//操作符进行整数除法(即无余数的商);而在python 2中,/操作符只是整数除法,除非其中一个操作数已经是浮点数。

在python 2.x中:

1
2
3
4
5
6
7
>>> 10/3
3
>>> # to get a floating point number from integer division:
>>> 10.0/3
3.3333333333333335
>>> float(10)/3
3.3333333333333335

在python 3中:

1
2
3
4
>>> 10/3
3.3333333333333335
>>> 10//3
3

如需进一步参考,请参阅PEP238。


//是无条件的"地板部门",例如:

1
2
>>> 4.0//1.5
2.0

正如你所看到的,尽管两个操作数都是float//仍然是楼层——所以你总是安全地知道它将要做什么。

根据python版本、将来的导入,甚至运行python的标志(例如…)的不同,单个/可能会也可能不会运行。

1
2
3
4
$ python2.6 -Qold -c 'print 2/3'
0
$ python2.6 -Qnew -c 'print 2/3'
0.666666666667

如您所见,单个/可以浮动,也可以基于完全非本地问题返回浮动,直到并包括-Q标志的值…;-)。

所以,如果你知道你想要地板,一定要使用//,这就保证了。当你知道你不想要地板时,用一个float()环绕另一个操作数,然后使用/。任何其他的组合,你都要服从于版本、导入和标志!-)


为了补充Alex的回答,我想补充一点,从python 2.2.0a 2开始,from __future__ import division是使用大量float(…)/…的一种方便的替代方法。除带//的分区外,所有分区都执行浮动分区。这适用于2.2.0A2中的所有版本。


为了补充这些其他答案,//操作符也提供了比/更大的(3x)性能优势,假设您需要整数除法。

1
2
3
4
5
6
7
8
$ python -m timeit '20.5 // 2'
100000000 loops, best of 3: 0.0149 usec per loop
$ python -m timeit '20.5 / 2'
10000000 loops, best of 3: 0.0484 usec per loop
$ python -m timeit '20 / 2'
10000000 loops, best of 3: 0.043 usec per loop
$ python -m timeit '20 // 2'
100000000 loops, best of 3: 0.0144 usec per loop


对于返回值类型为float的除法,可以将//视为math.floor()的别名。对于返回值为int类型的分部,它的作用是no-op

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import math
# let's examine `float` returns
# -------------------------------------
# divide
>>> 1.0 / 2
0.5
# divide and round down
>>> math.floor(1.0/2)
0.0
# divide and round down
>>> 1.0 // 2
0.0

# now let's examine `integer` returns
# -------------------------------------
>>> 1/2
0
>>> 1//2
0