В чем причина наличия "//" в 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