336 Целочисленное деление

Стандартный символ деления ( / ) работает по- разному в Python 3 и Python 2 , когда применяется к целым числам.

При делении целого числа на другое целое число в Python 3, операция деления x / y представляет собой истинное деление (использует __truediv__ метод) и дает результат с плавающей точкой. В том же время, та же операция в Python 2 представляет собой классическое деление , которая округляется результат вниз к отрицательной бесконечности (также известной как взятие на поле).

Например:

Код Выход Python 2 Выход Python 3
3 / 2 1 1,5
2 / 3 0 0,6666666666666666
-3 / 2 -2 -1,5

Поведение округление- в сторону ноль был устаревшим в Python 2.2 , но остается в Python 2.7 для обратной совместимости и был удален в Python 3.

Примечание: Для того, чтобы получить результат с плавающей точкой в Python 2 (без пола округления) мы можем указать один из операндов с десятичной точкой. Выше пример 2/3 , который дает 0 в Python 2 , должны быть использованы в качестве 2 / 3.0 или 2.0 / 3 или 2.0/3.0 , чтобы получить 0.6666666666666666

Код Выход Python 2 Выход Python 3
3.0 / 2.0 1,5 1,5
2 / 3.0 0,6666666666666666 0,6666666666666666
-3.0 / 2 -1,5 -1,5

Существует также оператор пола деления ( // ), который работает так же , как в обеих версиях: она округляется до ближайшего целого числа. (хотя поплавок возвращается при использовании поплавков) В обоих версиях // оператор карты для __floordiv__ .

Код Выход Python 2 Выход Python 3
3 // 2 1 1
2 // 3 0 0
-3 // 2 -2 -2
3.0 // 2.0 1,0 1,0
2.0 // 3 0.0 0.0
-3 // 2.0 -2,0 -2,0

Можно явно обеспечивать истинное деление или деление пола с использованием собственных функций в operator модуле:

 from operator import truediv, floordiv
assert truediv(10, 8) == 1.25            # equivalent to `/` in Python 3
assert floordiv(10, 8) == 1              # equivalent to `//`

 

Хотя операторные функции для каждого деления понятны и явны, они могут быть утомительными. Изменение поведения / часто будет предпочтительным оператором. Обычная практика является устранение типичного поведения деления пути добавления from __future__ import division в качестве первого оператора в каждом модуле:

 # needs to be the first statement in a module
from __future__ import division

 
Код Выход Python 2 Выход Python 3
3 / 2 1,5 1,5
2 / 3 0,6666666666666666 0,6666666666666666
-3 / 2 -1,5 -1,5

from __future__ import division гарантирует , что / оператор представляет истинное деление и только в модулях , которые содержат __future__ импорт, так что нет никаких веских причин не позволяет ей во всех новых модулях.

Примечание: Некоторые другие языки программирования используют округление к нулю (усечение) , а не округление вниз к отрицательной бесконечности , как это делает Python (т.е. на этих языках -3 / 2 == -1 ). Такое поведение может создать путаницу при переносе или сравнении кода.


Обратите внимание на флоат операндами: В качестве альтернативы from __future__ import division , можно было бы использовать символ обычное разделение / и гарантировать , что по крайней мере один из операндов с плавающей точкой: 3 / 2.0 == 1.5 . Однако это можно считать плохой практикой. Это слишком просто , чтобы написать average = sum(items) / len(items) и забудьте бросить один из аргументов , чтобы плавать. Кроме того, такие случаи часто могут уйти от внимания во время тестирования, например, если вы тестируете на массив , содержащий float с , но получить массив int s в производстве. Кроме того, если тот же код используется в Python 3, программа, планирующая 3 / 2 == 1 , чтобы быть правдой не будет работать правильно.

См PEP 238 для более детального обоснования , почему оператор деления был изменен в Python 3 и почему деление старого стиля следует избегать.


Смотрите Simple Math тему больше о разделении.