Jaki jest wynik% w Pythonie?


Odpowiedzi:


304

Operator% (modulo) zwraca resztę z podziału pierwszego argumentu na drugi. Argumenty liczbowe są najpierw konwertowane na typ wspólny. Zerowy argument zerowy podnosi wyjątek ZeroDivisionError. Argumentami mogą być liczby zmiennoprzecinkowe, np. 3,14% 0,7 równa się 0,34 (ponieważ 3,14 równa się 4 * 0,7 + 0,34.) Operator modulo zawsze daje wynik o takim samym znaku jak drugi argument (lub zero); wartość bezwzględna wyniku jest ściśle mniejsza niż wartość bezwzględna drugiego argumentu [2].

Zaczerpnięte z http://docs.python.org/reference/expressions.html

Przykład 1: 6%2 ocenia na, 0ponieważ nie ma reszty, jeśli 6 jest podzielone przez 2 (3 razy).

Przykład 2 : 7%2ocenia na, 1ponieważ pozostała część, 1gdy 7 jest dzielone przez 2 (3 razy).

Podsumowując, zwraca pozostałą część operacji dzielenia lub 0jeśli nie ma żadnej pozostałej części. Więc 6%2pomocą znaleźć resztę 6 podzielonej przez 2.


7
Dlaczego wszystkie przykłady mają większą liczbę po prawej stronie? Czy ktoś może wyjaśnić wynik 2% 6, co daje 2?
wookie

8
Pierwsza liczba to licznik, a druga mianownik. W twoim przykładzie 2 podzielone przez 6 to 0 reszta 2, dlatego wynik to 2.
David

4
Zaktualizuj swoją odpowiedź, poniżej znajdują się dokładniejsze odpowiedzi. W C / C ++ % oznacza „rem”, podczas gdy w Python% oznacza „mod”. np. - 21 % 4ma 3 w Pythonie.
Azam

Czy możesz wyjaśnić, dlaczego -11%5 = 4?
dahiya_boy

@ dahiya_boy Dodałem wyjaśnienie GvR do mojej mniej uprzywilejowanej odpowiedzi poniżej.
Paulo Scardine

143

Nieco tematycznie %jest również używany w operacjach formatowania ciągów, takich jak %=zamiana wartości na ciąg:

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

Ponownie, poza tematem, ale wydaje się, że jest to trochę udokumentowana funkcja, która zajęła mi trochę czasu, aby ją wyśledzić, i pomyślałem, że jest to związane z obliczeniami modulo Pythona, dla których ta strona SO zajmuje wysoką pozycję.


Czy istnieje logika dla%, która jest również używana jako odniesienie do formatowania łańcucha, czy to tylko przypadek historii, że ten symbol został przeciążony? Czy to powinno być jej własne pytanie?
WAF

5
Słabo udokumentowane? Nie sądzę: Operacje formatowania ciągów
KurzedMetal

@KurzedMetal - %=nie pojawia się na tej stronie
P. Myer Nore

@WAF %Operator został wybrany, ponieważ odzwierciedla specyfikacje procentowe użyte w samym ciągu.
MI Wright,

@ P.MyerNore Wiem, że to prawie 3 lata później, ale może pomóc innym. Przeczytaj pierwszy wyróżniony akapit w sek. 5.6.2 połączone powyżej przez KurzedMetal. „X% = {}” to po prostu skrót dla „x = x% {...}”
Sujay Phadke,

58

Wyrażenie podobne x % yjest do reszty x ÷ y- cóż, technicznie jest to „moduł” zamiast „przypomnienia”, więc wyniki mogą być inne, jeśli porównasz z innymi językami, w których %operator reszty. Istnieją pewne subtelne różnice (jeśli jesteś zainteresowany praktycznymi konsekwencjami, zobacz także poniżej „Dlaczego podłogi Integer Division Pythona” poniżej).

Pierwszeństwo jest takie samo jak operatorów /(dzielenie) i *(mnożenie).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 podzielone przez 2 jest równe 4.
  • 4 razy 2 to 8
  • 9 minus 8 to 1 - reszta.

Python gotcha : w zależności od używanej wersji Pythona %jest także (przestarzałym) operatorem interpolacji ciągów, więc uważaj, jeśli pochodzisz z języka z automatycznym rzutowaniem typów (np. PHP lub JS), w którym wyrażenie takie '12' % 2 + 3jest dozwolone: ​​w Python spowoduje, że TypeError: not all arguments converted during string formattingprawdopodobnie będzie to dla ciebie dość mylące.

[aktualizacja dla Python 3]

Komentarze użytkownika n00p:

9/2 ma 4,5 w pythonie. Musisz wykonać dzielenie liczb całkowitych w ten sposób: 9 // 2, jeśli chcesz, aby python powiedział ci, ile całych obiektów pozostało po dzieleniu (4).

Mówiąc dokładniej, podział liczb całkowitych był domyślnym ustawieniem w Pythonie 2 (uwaga: ta odpowiedź jest starsza niż mój chłopiec, który jest już w szkole i w tamtym czasie 2.x był głównym nurtem):

$ 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

Rzeczywiście we współczesnych 9 / 2wynikach 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

[aktualizacja]

Użytkownik dahiya_boy zapytał w sesji komentowania:

P: Czy możesz wyjaśnić, dlaczego -11 % 5 = 4- dahiya_boy

To dziwne, prawda? Jeśli spróbujesz tego w JavaScript:

> -11 % 5
-1

Wynika to z faktu, że w JavaScript %jest operatorem „resztki”, podczas gdy w Pythonie jest operatorem „modułu” (matematyki zegarowej).

Możesz uzyskać wyjaśnienie bezpośrednio z GvR :


Edycja - dahiya_boy

W Javie i iOS -11 % 5 = -1natomiast w Pythonie i Ruby -11 % 5 = 4.

Cóż, połowa przyczyny jest wyjaśniona przez Paulo Scardine , a reszta wyjaśnienia znajduje się poniżej

W Javie i iOS %daje resztę, co oznacza, że ​​jeśli podzielisz 11% 5 daje, Quotient = 2 and remainder = 1a -11% 5 daje Quotient = -2 and remainder = -1.

Przykładowy kod w szybkim iOS.

wprowadź opis zdjęcia tutaj

Ale kiedy mówimy o pythonie, daje on moduł zegara. I jego praca z poniższym wzorem

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

To znaczy,

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

Więc, mod(11,5) = 1

I

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

Więc, mod(-11,5) = 4

Przykładowy kod w python 3.0.

wprowadź opis zdjęcia tutaj


Dlaczego podłogi Integer Division Pythona

Zostałem poproszony (ponownie) dzisiaj o wyjaśnienie, dlaczego podział liczb całkowitych w Pythonie zwraca dolną część wyniku zamiast obcinania do zera jak C.

W przypadku liczb dodatnich nie ma niespodzianki:

>>> 5//2
2

Ale jeśli jeden z operandów jest ujemny, wynik jest zmienny, tzn. Zaokrąglony od zera (w kierunku ujemnej nieskończoności):

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

Niepokoi to niektórych ludzi, ale istnieje dobry powód matematyczny. Operacja dzielenia liczb całkowitych (//) i jej rodzeństwo, operacja modulo (%) idą w parze i spełniają ładny związek matematyczny (wszystkie zmienne są liczbami całkowitymi):

a/b = q with remainder r

takie, że

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

(zakładając, że aib są> = 0).

Jeśli chcesz, aby relacja rozszerzała się na ujemną a (utrzymując b dodatnią), masz dwie możliwości: jeśli skrócisz q w kierunku zera, r stanie się ujemne, tak że niezmiennik zmieni się na 0 <= abs (r) <w przeciwnym razie może piętro q w kierunku ujemnej nieskończoności, a niezmiennikiem pozostaje 0 <= r <b. [aktualizacja: naprawiono ten akapit]

W matematycznej teorii liczb matematycy zawsze preferują ten drugi wybór (patrz np. Wikipedia ). W przypadku Pythona dokonałem tego samego wyboru, ponieważ istnieje kilka interesujących zastosowań operacji modulo, w których znak a jest nieciekawy. Zastanów się nad wzięciem znacznika czasu POSIX (w sekundach od początku 1970 r.) I nadaniem mu pory dnia. Ponieważ dziennie jest 24 * 3600 = 86400 sekund, obliczenia te wynoszą po prostu t% 86400. Ale gdybyśmy wyrażali czasy przed 1970 rokiem przy użyciu liczb ujemnych, zasada „obcięcia do zera” dałaby bezsensowny wynik! Korzystanie z reguły podłogi wszystko działa dobrze.

Inne aplikacje, o których myślałem, to obliczenia pozycji pikseli w grafice komputerowej. Jestem pewien, że jest ich więcej.

Nawiasem mówiąc, dla ujemnego b wszystko się po prostu odwraca, a niezmiennik staje się:

0 >= r > b.

Dlaczego więc C nie robi tego w ten sposób? Prawdopodobnie sprzęt tego nie zrobił w czasie projektowania C. Sprzęt prawdopodobnie nie zrobił tego w ten sposób, ponieważ na najstarszym sprzęcie liczby ujemne były reprezentowane jako „znak + wielkość”, a nie reprezentacja uzupełnienia dwóch używana obecnie (przynajmniej dla liczb całkowitych). Mój pierwszy komputer był komputerem mainframe Control Data i używał swojego uzupełnienia do liczb całkowitych i liczb zmiennoprzecinkowych. Wzór 60 oznaczał zero ujemne!

Tim Peters, który wie, gdzie są pochowane wszystkie szkielety zmiennoprzecinkowe Pythona, wyraził pewne obawy o moje pragnienie rozszerzenia tych reguł na zmiennoprzecinkowy moduł. Prawdopodobnie ma rację; reguła skracania w kierunku ujemnej nieskończoności może powodować utratę precyzji dla x% 1,0, gdy x jest bardzo małą liczbą ujemną. Ale to nie wystarcza, bym przełamał liczbę całkowitą modulo i // jest z tym ściśle związany.

PS. Zauważ, że używam // zamiast / - jest to składnia Python 3, a także dozwolone w Python 2, aby podkreślić, że wiesz, że wywołujesz dzielenie liczb całkowitych. Operator / w Pythonie 2 jest niejednoznaczny, ponieważ zwraca inny wynik dla dwóch argumentów całkowitych niż dla liczb całkowitych i liczb zmiennoprzecinkowych lub dwóch liczb zmiennoprzecinkowych. Ale to zupełnie osobna historia; patrz PEP 238.

Wysłane przez Guido van Rossuma o 09:49


1
Również help(divmod)dokumentuje niezmiennego q, r = divmod(x y) <==> q*y + r == x.
chepner

49

Moduł jest operacją matematyczną, czasami opisywaną jako „arytmetyka zegara”. Uważam, że opisywanie go jako zwykłej reszty jest mylące i mylące, ponieważ maskuje prawdziwy powód, dla którego jest tak często używany w informatyce. Naprawdę służy do owijania cykli.

Pomyśl o zegarze: załóżmy, że patrzysz na zegar w czasie „wojskowym”, w którym zakres czasów wynosi od 0:00 do 23,59. Teraz, jeśli chcesz, aby coś działo się codziennie o północy, chciałbyś, aby bieżący czas mod 24 wynosił zero:

jeśli (godzina% 24 == 0):

Możesz pomyśleć o wszystkich godzinach w historii, które owijają się w kółko 24 godzin w kółko, a obecna godzina dnia to nieskończenie długi numer mod 24. Jest to znacznie głębsza koncepcja niż tylko reszta, jest to sposób matematyczny radzić sobie z cyklami i jest to bardzo ważne w informatyce. Służy także do owijania tablic, co pozwala zwiększyć indeks i użyć modułu, aby zawinąć do początku po osiągnięciu końca tablicy.


1
Oto jak jest on zaimplementowany w Pythonie:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani


7

W większości języków% służy do modułu . Python nie jest wyjątkiem.


11
O ile widzę, Python jest niezwykły, ponieważ używa% do modułu; Fortran, C / C ++ i Java używają% jako reszty. (Patrz stackoverflow.com/questions/13683563/… , różnice dotyczą sposobu postępowania z wartościami ujemnymi i ułamkowymi.) Języki, które wprowadzają rozróżnienie (np. Ada, Haskell i Schemat) używają słów „rem” i „mod” (lub „reszta” i „modulo”) zamiast%.
Jim Pivarski

5
Aktualizacja: Znalazłem tę świetną tabelę operacji modulo / pozostałości według języka en.wikipedia.org/wiki/Modulo_operation . Python jest niezwykły, ale nie wyjątkowy (na przykład TCL i Lua mają wspólną konwencję Pythona.)
Jim Pivarski


4

x % yoblicza pozostałą część dzielenia xpodzieloną przez ygdzie iloraz jest liczbą całkowitą . Reszta ma znak y.


W Pythonie 3 obliczenia dają wynik 6.75; /dzieje się tak, ponieważ robi prawdziwy podział, a nie całkowity, taki jak (domyślnie) w Pythonie 2. W Python 2 1 / 4daje 0, ponieważ wynik jest zaokrąglany w dół.

Podziału liczb całkowitych można również dokonać w języku Python 3 za pomocą //operatora, dlatego aby uzyskać wynik 7, można wykonać:

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

Możesz także uzyskać podział stylu Python na Python 2, po prostu dodając wiersz

from __future__ import division

jako pierwsza linia kodu źródłowego w każdym pliku źródłowym.


8
Pamiętaj, że dzieci #są dla komentarzy i //są operatorami.
Mike Causer

3

Operator modułu służy zwykle do dzielenia reszty na liczbach całkowitych, zazwyczaj w Pythonie można go stosować do liczb zmiennoprzecinkowych.

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

Operator% (modulo) zwraca resztę z podziału pierwszego argumentu na drugi. Argumenty liczbowe są najpierw konwertowane na typ wspólny. Zerowy argument zerowy podnosi wyjątek ZeroDivisionError. Argumentami mogą być liczby zmiennoprzecinkowe, np. 3,14% 0,7 równa się 0,34 (ponieważ 3,14 równa się 4 * 0,7 + 0,34.) Operator modulo zawsze daje wynik o takim samym znaku jak drugi argument (lub zero); wartość bezwzględna wyniku jest ściśle mniejsza niż wartość bezwzględna drugiego argumentu [2].


3

Jest to operacja modulo, z wyjątkiem gdy jest to staromodny operator formatowania ciągów w stylu C, a nie operacja modulo . Zobacz tutaj, aby uzyskać szczegółowe informacje. Zobaczysz dużo tego w istniejącym kodzie.


3

Istnieje również przydatna wbudowana funkcja o nazwie divmod:

divmod (a, b)

Weź dwie (niezłożone) liczby jako argumenty i zwróć parę liczb składającą się z ich ilorazu i reszty, jeśli używasz długiego dzielenia.


2

Miej świadomość, że

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

nawet z nawiasami daje 6,75 zamiast 7, jeśli jest obliczane w Pythonie 3.4.


A operator „/” również nie jest tak łatwy do zrozumienia (python2.7): spróbuj ...

- 1/4

1 - 1/4

To trochę nie na temat, ale należy to wziąć pod uwagę przy ocenie powyższego wyrażenia :)


2
Jak miałoby to być 7? Upraszcza to (1)+(0)-(0.25)+(6).
J.Steve,

1

Ciężko mi było znaleźć konkretne przypadki użycia dla% online, np. Dlaczego podział ułamkowego modułu lub ujemny podział modułu skutkuje odpowiedzią, którą robi. Mam nadzieję, że pomoże to wyjaśnić takie pytania:

Podział modułu ogólnie:

Podział modułu zwraca pozostałą część operacji dzielenia matematycznego. Robi to w następujący sposób:

Załóżmy, że mamy dywidendę 5 i dzielnik 2, następująca operacja dzielenia byłaby (równa x):

dividend = 5
divisor = 2

x = 5/2 
  1. Pierwszym krokiem w obliczeniu modułu jest przeprowadzenie podziału na liczby całkowite:

    x_int = 5 // 2 (dzielenie liczb całkowitych w pythonie używa podwójnego ukośnika)

    x_int = 2

  2. Następnie wynik x_int jest mnożony przez dzielnik:

    x_mult = x_int * dzielnik x_mult = 4

  3. Na koniec dywidenda jest odejmowana od x_mult

    dywidenda - x_mult = 1

  4. Operacja modułu zwraca zatem 1:

    5% 2 = 1

Aplikacja do zastosowania modułu ułamka

Example: 2 % 5 

Obliczenie modułu przy zastosowaniu do ułamka jest takie samo jak powyżej; ważne jest jednak, aby pamiętać, że podział na liczbę całkowitą spowoduje, że wartość dzielenia będzie wynosić zero, gdy dzielnik będzie większy niż dywidenda:

dividend = 2 
divisor = 5

Dzielenie liczb całkowitych powoduje 0, podczas gdy; dlatego po wykonaniu kroku 3 powyżej wartość dywidendy jest przenoszona (odejmowana od zera):

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

Aplikacja do zastosowania modułu do ujemnego

Występuje podział podłogi, w którym wartość podziału na liczbę całkowitą jest zaokrąglana w dół do najniższej wartości całkowitej:

import math 

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

y = 1.1
math.floor = 1

Dlatego podczas dzielenia liczb całkowitych możesz uzyskać inny wynik niż się spodziewałeś!

Zastosowanie powyższych kroków w odniesieniu do następującej dywidendy i dzielnika ilustruje koncepcję modułu:

dividend: -5 
divisor: 2 

Krok 1: Zastosuj dzielenie liczb całkowitych

x_int = -5 // 2  = -3

Krok 2: Pomnóż wynik dzielenia liczb całkowitych przez dzielnik

x_mult = x_int * 2 = -6

Krok 3: Odejmij dywidendę ze zwielokrotnionej zmiennej, zauważ podwójne ujemne.

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

W związku z tym:

-5 % 2 = 1

0

Operator% (modulo) zwraca resztę z podziału pierwszego argumentu na drugi. Argumenty liczbowe są najpierw konwertowane na typ wspólny.

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

Jest to oparte na pierwszeństwie operatora.


0

%jest modulo . 3 % 2 = 1,4 % 2 = 0

/ jest (w tym przypadku liczbą całkowitą), więc:

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



0

Moduł - dzieli operand lewej ręki przez operand prawej ręki i zwraca resztę.

Jeśli to pomaga:

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

... i tak dalej.


0

Odkryłem, że najłatwiejszym sposobem uchwycenia operatora modułu (%) jest długi podział. Jest to reszta i może być przydatna w określaniu liczby parzystej lub nieparzystej:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

pozostała część dywizji niewiele do wzięcia
DeafaltCoder
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.