Який результат% у 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_'

Знову ж таки, поза темою, але, здається, це трохи задокументована функція, яка зайняла мені деякий час, щоб відстежити, і я подумав, що це пов’язано з розрахунком модуля пітонів, для якого ця SO-сторінка займає високу позицію.


Чи є логіка, щоб% також використовувались як посилання на форматування рядків чи це просто випадковість історії, що цей символ був перевантажений? Це має бути власне питання?
WAF

5
Погано задокументовано? Я не думаю, що так: Операції з форматування рядків
KurzedMetal

@KurzedMetal - %=не відображається на цій сторінці
P. Myer Nore

@WAF %Оператор був вибраний, оскільки він відображає специфікатори відсотків, що використовуються в самій рядку.
М. І. Райт

@ P.MyerNore Я знаю, що це майже через 3 роки, але може допомогти іншим. Прочитайте перший виділений пункт в сек. 5.6.2, пов'язаний вище KurzedMetal. "X% = {}" - це просто коротка форма для "x = x% {...}"
Sujay Phadke

58

Вираз на зразок x % yоцінюється до залишку x ÷ y- ну, технічно це "модуль" замість "нагадування", тому результати можуть бути різними, якщо порівнювати з іншими мовами, де %оператор залишку. Існують деякі тонкі відмінності (якщо вас цікавлять практичні наслідки, див. Також "Чому підлоги підрозділу Питона" нижче).

Пріоритетність - це те саме, що оператори /(ділення) та *(множення).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9, поділене на 2, дорівнює 4.
  • 4 рази 2 - 8
  • 9 мінус 8 - 1 - залишок.

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

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

Коментарі n00p користувача:

9/2 - 4,5 в пітоні. Ви повинні зробити ціле ділення так: 9 // 2, якщо ви хочете, щоб пітон повідомив вам, скільки цілих об'єктів залишилося після поділу (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

У сучасних 9 / 2результатах Python 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 - оператором "modulus" (тактова математика).

Пояснення можна отримати безпосередньо від GvR :


Редагувати - dahiya_boy

У Java та iOS, -11 % 5 = -1тоді як у python та ruby -11 % 5 = 4.

Добре половина причини пояснюється Пауло Скардіном , а решта пояснень - тут

У Java та iOS %дає решту, що означає, якщо розділити 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 повертає підсумок результату, а не обертається до нуля, як 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 я зробив той самий вибір, оскільки є кілька цікавих застосувань модульної операції, де знак a нецікавий. Подумайте про те, щоб взяти часову позначку 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 неоднозначний, оскільки він повертає інший результат для двох цілих операндів, ніж для int та float або двох floats. Але це абсолютно окрема історія; див. 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 години, і ця година сьогодні - це нескінченно довге число мод 24. Це набагато глибше поняття, ніж просто залишок, це математичний шлях мати справу з циклами, і це дуже важливо в інформатиці. Він також використовується для обгортання масивів, що дозволяє збільшити індекс і використовувати модуль, щоб повернутись до початку після досягнення кінця масиву.


1
Ось як це реалізовано в Python:a % b = a - b * floor(a/b)
Ейман Аль-Еріані


7

У більшості мов% використовується для модулів . Python не є винятком.


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

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

      # % 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].


3

Це модульна операція, за винятком випадків, коли це старомодний оператор форматування рядків у стилі C, а не операція модуля . Детальніше дивіться тут . Ви побачите багато цього в існуючому коді.


3

Також є корисна вбудована функція під назвою divmod:

divmod (a, b)

Візьміть два (нескладні) числа як аргументи і поверніть пару чисел, що складаються з їхнього коефіцієнта та залишку, коли використовуєте довгий поділ.


2

Будьте в курсі цього

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

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


І оператор '/' теж не так легко зрозуміти (python2.7): спробуйте ...

- 1/4

1 - 1/4

Це тут трохи поза темою, але це слід враховувати, оцінюючи вищенаведений вираз :)


2
Як це колись буде 7? Це спрощує до (1)+(0)-(0.25)+(6).
J.Steve

1

Мені важко було легко знайти конкретні випадки використання для використання в Інтернеті%, наприклад, чому виконання дробового поділу модулів або негативного поділу модуля призводить до відповіді, що це робиться. Сподіваюсь, це допоможе з’ясувати такі питання:

Відділ модулів Загалом:

Модульний поділ повертає решту операції математичного поділу. Це робиться так:

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

dividend = 5
divisor = 2

x = 5/2 
  1. Першим кроком при обчисленні модуля є проведення цілого поділу:

    x_int = 5 // 2 (ціле ділення в python використовує подвійну косу рису)

    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

0

Оператор% (модуль) отримує залишок від ділення першого аргументу на другий. Числові аргументи спочатку перетворюються на загальний тип.

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

Це ґрунтується на перевазі оператора.


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

... і так далі.


0

Я виявив, що найпростіший спосіб зрозуміти оператор модуля (%) - через довгий поділ. Він є залишком і може бути корисним для визначення числа, парного чи непарного:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

дає решту підрозділу не так багато, щоб взяти участь
DeafaltCoder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.