В чем причина наличия "//" в Python?
Я видел это у кого-то кода:
y = img_index // num_images
где img_index
- текущий индекс, а num_images
- 3.
Когда я запутался с //
в IPython, он действует так же, как знак разделения (т.е. одна косая черта). Мне просто интересно, есть ли причина иметь двойные косые черты?
Ответы
Ответ 1
В Python 3 оператор /
выполнил деление с плавающей запятой и добавил оператор //
для выполнения целочисленного деления (т.е. частного без остатка); тогда как в Python 2 оператор /
был просто целым делением, если только один из операндов уже не был числом с плавающей запятой.
В 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.
Ответ 2
//
безоговорочно "разделение полов", например:
>>> 4.0//1.5
2.0
Как вы видите, хотя оба операнда float
s, //
полы - так что вы всегда точно знаете, что он собирается делать.
Одиночный /
может или не может выполняться в зависимости от выпуска Python, будущих импортов и даже флагов, на которых выполняется Python, например....
$ python2.6 -Qold -c 'print 2/3'
0
$ python2.6 -Qnew -c 'print 2/3'
0.666666666667
Как вы видите, одиночный /
может занимать пол, или, он может возвращать float, основанный на полностью нелокальных проблемах, вплоть до значения флага -Q
..; -.)
Итак, если и когда вы знаете, вам нужен пол, всегда используйте //
, что гарантирует его. Если и когда вы знаете, что вы не хотите полы, нажмите float()
вокруг другого операнда и используйте /
. Любая другая комбинация, и вы во власти версии, импорта и флагов! -)
Ответ 3
Чтобы дополнить ответ Alex, я бы добавил, что начиная с Python 2.2.0a2, from __future__ import division
является удобной альтернативой использованию большого количества float(…)/…
. Все деления выполняют поплавковые деления, кроме тех, у которых //
. Это работает со всеми версиями из 2.2.0a2.
Ответ 4
В дополнение к этим другим ответам оператор //
также предлагает значительные (3x) преимущества производительности по сравнению с /
, предполагая, что вы хотите целочисленное деление.
$ 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
Ответ 5
//
можно считать псевдонимом math.floor() для делений с возвращаемым значением типа float
. Он работает как no-op
для делений с возвращаемым значением типа int
.
import math
# let 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 examine `integer` returns
# -------------------------------------
>>> 1/2
0
>>> 1//2
0