Каков результат% в Python?

241

Что входит %в расчет? Я не могу понять, что он делает.

Например, он вычисляет процент от расчета: 4 % 2по-видимому, равен 0. Как?

оранжевый
источник

Ответы:

304

Оператор% (по модулю) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются в общий тип. Нулевой правый аргумент вызывает исключение ZeroDivisionError. Аргументами могут быть числа с плавающей запятой, например, 3,14% 0,7 равно 0,34 (поскольку 3,14 равно 4 * 0,7 + 0,34.) Оператор по модулю всегда дает результат с тем же знаком, что и его второй операнд (или ноль); абсолютное значение результата строго меньше, чем абсолютное значение второго операнда [2].

Взято с http://docs.python.org/reference/expressions.html

Пример 1: 6%2 оценивается, 0потому что нет остатка, если 6 делится на 2 (3 раза).

Пример 2 : 7%2оценивается, 1потому что есть остаток от 1деления 7 на 2 (3 раза).

Таким образом, чтобы подвести итог, он возвращает остаток от операции деления, или 0если нет остатка. Значит, 6%2найдите остаток от 6, деленный на 2.

медер омуралиев
источник
7
Почему все примеры имеют большее число справа? Может кто-нибудь объяснить результат 2% 6, который дает 2?
Вуки
8
Первое число - это числитель, а второе - знаменатель. В вашем примере 2, деленное на 6, равно 0 остатку 2, поэтому результат равен 2.
Дэвид
4
Пожалуйста, обновите свой ответ, ниже приведены более точные ответы. В C / C ++ % для «rem», тогда как в Python% для «mod». например - 21 % 4, 3 в Python.
Азам
Не могли бы вы объяснить, почему -11%5 = 4?
dahiya_boy
@dahiya_boy Я добавил объяснение GvR к моему менее одобренному ответу ниже.
Пауло Скардин
143

Несколько не по теме, %также используется в операциях форматирования строки, например, %=для подстановки значений в строку:

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

Опять же, не по теме, но, похоже, это была небольшая документированная особенность, которую мне потребовалось некоторое время, чтобы отследить, и я подумал, что это связано с вычислением по модулю Pythons, для которого эта SO-страница высоко оценивается.

mrmagooey
источник
Есть ли логика для%, также используемого в качестве ссылки форматирования строки, или это просто случайность истории, что этот символ был перегружен? Должен ли это быть его собственный вопрос?
WAF
5
Плохо документированы? Я так не думаю: операции форматирования строк
KurzedMetal
@KurzedMetal - %=не отображается на этой странице
П. Майер Нор
@WAF %Оператор был выбран, потому что он отражает спецификаторы процентов, используемые в самой строке.
М.И. Райт
@ P.MyerNore Я знаю, что это почти 3 года спустя, но может помочь другим. Прочитайте первый выделенный пункт в с. 5.6.2, связанный выше KurzedMetal. "X% = {}" - это просто краткая форма для "x = x% {...}"
Суджай Пхадке
58

Выражение like x % yоценивает остаток от ... x ÷ yну, технически это «модуль» вместо «напоминание», поэтому результаты могут отличаться, если вы сравниваете с другими языками, где %есть оператор остатка. Есть некоторые тонкие различия (если вас интересуют практические последствия, см. Также «Почему полы с целочисленным делением в Python» ниже).

Приоритет такой же, как у операторов /(деление) и *(умножение).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9, деленное на 2, равно 4.
  • 4 раза 2 - 8
  • 9 минус 8 это 1 - остаток.

Гипотеза Python : в зависимости от используемой версии Python %также является (устаревшим) оператором интерполяции строк, так что следите, если вы пришли из языка с автоматическим приведением типов (например, PHP или JS), где выражение вроде '12' % 2 + 3допустимо: Python приведет к тому, TypeError: not all arguments converted during string formattingчто, вероятно, будет довольно запутанным для вас.

[обновление для Python 3]

Пользователь n00p комментирует:

9/2 - это 4,5 в питоне. Вы должны выполнить целочисленное деление следующим образом: 9 // 2, если вы хотите, чтобы python сообщал вам, сколько всего объектов осталось после деления (4).

Чтобы быть точным, целочисленное деление раньше использовалось по умолчанию в Python 2 (учтите, этот ответ старше моего мальчика, который уже учился в школе и в то время, когда 2.x были мейнстримом):

$ python2.7
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1

В современном Python 9 / 2результаты 4.5действительно:

$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1

[Обновить]

Пользователь dahiya_boy спросил в комментариях:

В. Можете ли вы объяснить, почему -11 % 5 = 4- dahiya_boy

Это странно, правда? Если вы попробуете это в JavaScript:

> -11 % 5
-1

Это связано с тем, что в JavaScript %это оператор «остаток», а в Python это оператор «модуль» (Clock Math).

Вы можете получить объяснение непосредственно от GvR :


Редактировать - dahiya_boy

В Java и iOS, -11 % 5 = -1тогда как в python и ruby -11 % 5 = 4.

Ну, половина причины объясняется Пауло Скардином , а остальное объяснение здесь ниже

В Java и прошивкой, %дает остаток , что означает , если вы разделите на 11% 5 дает Quotient = 2 and remainder = 1и -11% 5 дает Quotient = -2 and remainder = -1.

Пример кода в быстрой iOS.

введите описание изображения здесь

Но когда мы говорим о Python, он дает модуль часов. И его работа с формулой ниже

mod(a,n) = a - {n * Floor(a/n)}

Это значит,

mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}

Так, mod(11,5) = 1

И

mod(-11,5) = -11 - 5 * Floor(11/5) => -11 - {5 * (-3)}

Так, mod(-11,5) = 4

Пример кода в Python 3.0.

введите описание изображения здесь


Почему полы целочисленного деления Python

Меня попросили (снова) сегодня объяснить, почему целочисленное деление в Python возвращает пол результата вместо усечения до нуля, как C.

Для положительных чисел нет ничего удивительного:

>>> 5//2
2

Но если один из операндов отрицателен, результат получается беспорядочным, то есть округляется от нуля (в сторону отрицательной бесконечности):

>>> -5//2
-3
>>> 5//-2
-3

Это беспокоит некоторых людей, но есть веская математическая причина. Операция целочисленного деления (//) и ее брат, операция по модулю (%) идут вместе и удовлетворяют хорошим математическим отношениям (все переменные являются целыми числами):

a/b = q with remainder r

такой, что

b*q + r = a and 0 <= r < b

(при условии, что a и b>> 0).

Если вы хотите, чтобы отношение расширилось до отрицательного значения a (сохраняя положительное значение b), у вас есть два варианта: если вы укоротите q до нуля, r станет отрицательным, так что инвариант изменится на 0 <= abs (r) <в противном случае, вы может пол q к отрицательной бесконечности, и инвариант остается 0 <= r <b. [обновление: исправил этот пункт]

В математической теории чисел математики всегда предпочитают второй вариант (см., Например, Википедию ). Для Python я сделал такой же выбор, потому что есть некоторые интересные приложения операции по модулю, где знак а неинтересен. Подумайте о том, чтобы взять метку времени POSIX (секунды с начала 1970 года) и перевести ее на время суток. Поскольку в день 24 * 3600 = 86400 секунд, это вычисление просто t% 86400. Но если бы мы выражали время до 1970 года с использованием отрицательных чисел, правило «обрезать до нуля» дало бы бессмысленный результат! Используя правило пола, все работает отлично.

Другие приложения, о которых я думал, это вычисления положения пикселей в компьютерной графике. Я уверен, что есть еще.

Кстати, для отрицательного b все просто переворачивается, и инвариант становится:

0 >= r > b.

Так почему же C не делает это таким образом? Вероятно, аппаратное обеспечение не делало этого во время разработки C. И аппаратное обеспечение, вероятно, не делало этого таким образом, потому что в самом старом аппаратном обеспечении отрицательные числа были представлены как «знак + величина», а не как дополнение к двум, используемое в наши дни (по крайней мере, для целых чисел). Моим первым компьютером был мэйнфрейм Control Data, и он использовал дополнение как для целых чисел, так и для чисел с плавающей точкой. Образец из 60 означал отрицательный ноль!

Тим Питерс, который знает, где похоронены все скелеты Python с плавающей точкой, выразил некоторое беспокойство по поводу моего желания распространить эти правила на модули с плавающей точкой. Он, вероятно, прав; Правило усечения к отрицательной бесконечности может привести к потере точности для x% 1.0, когда x - очень маленькое отрицательное число. Но этого не достаточно, чтобы разбить целое число по модулю, и я тесно связан с этим.

PS. Обратите внимание, что я использую // вместо / - это синтаксис Python 3, а также разрешено в Python 2 подчеркнуть, что вы знаете, что вызываете целочисленное деление. Оператор / в Python 2 является неоднозначным, поскольку он возвращает другой результат для двух целочисленных операндов, чем для целого числа и числа с плавающей точкой или двух чисел с плавающей точкой. Но это совершенно отдельная история; см. PEP 238.

Отправленный Гвидо ван Россумом в 9:49

Пауло Скардин
источник
1
Также help(divmod)документирует инвариант q, r = divmod(x y) <==> q*y + r == x.
Чепнер
49

Модуль - это математическая операция, иногда описываемая как «арифметика часов». Я считаю, что описание его просто как остатка вводит в заблуждение и вводит в заблуждение, потому что оно маскирует реальную причину, по которой он так часто используется в информатике. Это действительно используется, чтобы обернуть вокруг циклов.

Подумайте о часах. Предположим, вы смотрите на часы в «военное» время, где диапазон времени колеблется от 0:00 до 23,59. Теперь, если вы хотите, чтобы что-то происходило каждый день в полночь, вы бы хотели, чтобы текущее время мод 24 было равно нулю:

если (час% 24 == 0):

Вы можете думать о всех часах в истории, повторяющихся вокруг круга из 24 часов снова и снова, и текущий час дня - это бесконечно длинное число mod 24. Это гораздо более глубокая концепция, чем просто остаток, это математический способ. иметь дело с циклами, и это очень важно в информатике. Он также используется для обтекания массивов, что позволяет вам увеличивать индекс и использовать модуль для переноса назад в начало после достижения конца массива.

jarvis01123
источник
1
Вот как это реализовано в Python:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani
7

В большинстве языков% используется для модуля . Python не является исключением.

sorpigal
источник
11
Насколько я вижу, Python необычен тем, что использует% для модуля; Fortran, C / C ++ и Java используют% для обозначения остатка. (См. Stackoverflow.com/questions/13683563/… , различия заключаются в том, как обрабатываются отрицательные и дробные значения.) Языки, которые различают (например, Ada, Haskell и Scheme), используют слова «rem» и «mod» (или «остаток» и «по модулю»), а не%.
Джим Пиварски
5
Обновление: я нашел эту большую таблицу операций по модулю / остатку по языку en.wikipedia.org/wiki/Modulo_operation . Python необычен, но не уникален (например, TCL и Lua разделяют соглашение Python.)
Джим Пиварски
5

Оператор% Modulo также можно использовать для печати строк (как в C), как это определено в Google https://developers.google.com/edu/python/strings .

      # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

Это кажется немного не по теме, но это, безусловно, поможет кому-то.

Харшит Чаудхари
источник
4

x % yвычисляет остаток от деления, xделенный на то, yгде частным является целое число . Остальная часть имеет знак y.


На Python 3 расчет дает 6.75; это происходит потому, что /выполняется истинное деление, а не целочисленное деление, как (по умолчанию) в Python 2. В Python 2 1 / 4выдает 0, а результат округляется в меньшую сторону.

Целочисленное деление может быть выполнено и на Python 3, с //оператором, таким образом, чтобы получить 7 в результате, вы можете выполнить:

3 + 2 + 1 - 5 + 4 % 2 - 1 // 4 + 6

Кроме того, вы можете получить разделение стиля Python на Python 2, просто добавив строку

from __future__ import division

в качестве первой строки исходного кода в каждом исходном файле.

Антти Хаапала
источник
8
Помните, дети #для комментариев и //является оператором.
Майк Козер
3

Оператор модуля, он обычно используется для деления остатка на целые числа, но в Python может использоваться для чисел с плавающей запятой.

http://docs.python.org/reference/expressions.html

Оператор% (по модулю) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются в общий тип. Нулевой правый аргумент вызывает исключение ZeroDivisionError. Аргументами могут быть числа с плавающей запятой, например, 3,14% 0,7 равно 0,34 (поскольку 3,14 равно 4 * 0,7 + 0,34.) Оператор по модулю всегда дает результат с тем же знаком, что и его второй операнд (или ноль); абсолютное значение результата строго меньше, чем абсолютное значение второго операнда [2].

WKL
источник
3

Это операция по модулю, за исключением случаев, когда это устаревший оператор форматирования строк в стиле C, а не операция по модулю . Смотрите здесь для деталей. Вы увидите много этого в существующем коде.

Джон Мачин
источник
3

Также есть полезная встроенная функция divmod:

divmod (a, b)

Возьмите два (не комплексных) числа в качестве аргументов и верните пару чисел, состоящую из их частного и остатка при использовании длинного деления.

warvariuc
источник
2

Быть в курсе, что

(3 +2 + 1 - 5) + (4 % 2) - (1/4) + 6

даже в скобках результат равен 6,75 вместо 7, если он рассчитан в Python 3.4.


И оператор '/' тоже не так легко понять (python2.7): try ...

- 1/4

1 - 1/4

Это немного не по теме, но это следует учитывать при оценке приведенного выше выражения :)

Бернхард
источник
2
Как это будет 7? Это упрощает до (1)+(0)-(0.25)+(6).
J.Steve
1

Мне было трудно легко найти конкретные варианты использования% онлайн, например, почему деление с дробным модулем или деление с отрицательным модулем приводит к полученному ответу. Надеюсь, это поможет прояснить такие вопросы:

Модуль деления в целом:

Модуль деления возвращает остаток от математического деления. Это делает это следующим образом:

Скажем, у нас есть дивиденд 5 и делитель 2, следующая операция деления будет (приравнена к х):

dividend = 5
divisor = 2

x = 5/2 
  1. Первым шагом в расчете модуля является проведение целочисленного деления:

    x_int = 5 // 2 (целочисленное деление в питоне использует двойную косую черту)

    x_int = 2

  2. Затем вывод x_int умножается на делитель:

    x_mult = x_int * делитель x_mult = 4

  3. Наконец, дивиденд вычитается из x_mult

    дивиденд - x_mult = 1

  4. Следовательно, операция модуля возвращает 1:

    5% 2 = 1

Приложение для применения модуля к дроби

Example: 2 % 5 

Расчет модуля применительно к дроби такой же, как указано выше; однако важно отметить, что целочисленное деление приведет к значению ноль, когда делитель больше, чем дивиденд:

dividend = 2 
divisor = 5

Целочисленное деление приводит к 0, тогда как; следовательно, когда вышеуказанный шаг 3 выполняется, значение дивиденда переносится (вычитается из нуля):

dividend - 0 = 2  —> 2 % 5 = 2 

Приложение для применения модуля к отрицательному

Происходит деление по полу, при котором значение целочисленного деления округляется до наименьшего целочисленного значения:

import math 

x = -1.1
math.floor(-1.1) = -2 

y = 1.1
math.floor = 1

Поэтому, когда вы делаете целочисленное деление, вы можете получить результат, отличный от ожидаемого!

Применение описанных выше шагов к следующему дивиденду и делителю иллюстрирует концепцию модуля:

dividend: -5 
divisor: 2 

Шаг 1: применить целочисленное деление

x_int = -5 // 2  = -3

Шаг 2: Умножьте результат деления на целое на делитель

x_mult = x_int * 2 = -6

Шаг 3: Вычтите дивиденды из умноженной переменной, обратите внимание на двойной минус.

dividend - x_mult = -5 -(-6) = 1

Следовательно:

-5 % 2 = 1
N.Atanasov
источник
0

Оператор% (по модулю) возвращает остаток от деления первого аргумента на второй. Числовые аргументы сначала преобразуются в общий тип.

3 + 2 + 1 - 5 + 4% 2 - 1/4 + 6 = 7

Это основано на приоритетах операторов.

user225312
источник
0

%является по модулю . 3 % 2 = 1,4 % 2 = 0

/ есть (целое число в данном случае) деление, поэтому:

3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
1 + 4%2 - 1/4 + 6
1 + 0 - 0 + 6
7
Хачик
источник
0

Модуль - Делит левый операнд на правый операнд и возвращает остаток.

Если это поможет:

1:0> 2%6
=> 2
2:0> 8%6
=> 2
3:0> 2%6 == 8%6
=> true

... и так далее.

gr8scott06
источник
0

Я обнаружил, что самый простой способ понять оператор модуля (%) - это длинное деление. Это остаток и может быть полезен при определении числа, чтобы быть четным или нечетным:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2
JJJ
источник
дает оставшуюся часть подразделения не так много, чтобы принять
DeafaltCoder