我在某人的代码中看到:

y = img_index // num_images

其中img_index是一个运行索引,num_images是3。

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


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

在Python 2中。X:

>>> 10/3
3
>>> # To get a floating point number from integer division:
>>> 10.0/3
3.3333333333333335
>>> float(10)/3
3.3333333333333335

在Python 3中:

>>> 10/3
3.3333333333333335
>>> 10//3
3

详见PEP238。


//是无条件的“flooring division”,例如:

>>> 4.0//1.5
2.0

正如你所看到的,即使两个操作数都是浮点数,//仍然是浮点数——所以你总是安全地知道它要做什么。

单一/可能会或可能不会触底,这取决于Python版本、未来的导入,甚至Python运行的标志,例如:

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

如你所见,single / may floor,或者它可能返回一个浮点数,基于完全非本地的问题,直到并包括- q标志的值…;-)。

因此,如果并且当你知道你需要地板时,总是使用//,这保证了它。如果和当你知道你不需要地板时,在其他操作数周围加上float()并使用/。任何其他组合,你都要受版本、导入和标志的摆布!-)


为了补充Alex的回答,我想补充一点,从Python 2.2.0a2开始,从__future__导入除法是使用大量float(…)/....的方便替代方案所有除法都执行浮点除法,除了带有//的除法。这适用于2.2.0a2以上的所有版本。


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

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

为了补充这些其他答案,//运算符还提供了比/显著的(3x)性能优势,假设您想要整数除法。

$ python -m timeit '20.5 // 2'
100,000,000 loops, best of 3: 14.9 nsec per loop

$ python -m timeit '20.5 / 2'
 10,000,000 loops, best of 3: 48.4 nsec per loop

$ python -m timeit '20 / 2'
 10,000,000 loops, best of 3: 43.0 nsec per loop

$ python -m timeit '20 // 2'
100,000,000 loops, best of 3: 14.4 nsec per loop