Was ist das Ergebnis von% in Python?


241

Was macht das %in einer Berechnung? Ich kann nicht herausfinden, was es tut.

Funktioniert es zum Beispiel ein Prozent der Berechnung: 4 % 2ist anscheinend gleich 0. Wie?

Antworten:


304

Der% (Modulo) -Operator ergibt den Rest aus der Division des ersten Arguments durch das zweite. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert. Ein Null-Rechts-Argument löst die ZeroDivisionError-Ausnahme aus. Die Argumente können Gleitkommazahlen sein, z. B. 3,14% 0,7 entspricht 0,34 (da 3,14 4 * 0,7 + 0,34 entspricht). Der Modulo-Operator liefert immer ein Ergebnis mit demselben Vorzeichen wie sein zweiter Operand (oder Null). Der Absolutwert des Ergebnisses ist streng kleiner als der Absolutwert des zweiten Operanden [2].

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

Beispiel 1: Wird 6%2ausgewertet, 0da es keinen Rest gibt, wenn 6 durch 2 geteilt wird (3 Mal).

Beispiel 2 : wird 7%2ausgewertet, 1weil es einen Rest gibt, 1wenn 7 durch 2 geteilt wird (3 Mal).

Zusammenfassend gibt es den Rest einer Divisionsoperation zurück oder 0wenn es keinen Rest gibt. Also 6%2bedeutet, den Rest von 6 geteilt durch 2 zu finden.


7
Warum haben alle Beispiele rechts eine größere Zahl? Kann jemand das Ergebnis von 2% 6 erklären, was 2 ergibt?
Wookie

8
Die erste Zahl ist der Zähler und die zweite ist der Nenner. In Ihrem Beispiel 2 geteilt durch 6 ist 0 Rest 2, daher ist das Ergebnis 2.
David

4
Bitte aktualisieren Sie Ihre Antwort, es gibt genauere Antworten unten. In C / C ++ steht % für 'rem', während in Python% für 'mod' steht. zB - 21 % 4ist 3 in Python.
Azam

Können Sie bitte erklären, warum -11%5 = 4?
dahiya_boy

@dahiya_boy Ich habe die Erklärung von GvR zu meiner weniger optimierten Antwort unten hinzugefügt.
Paulo Scardine

143

Etwas abseits des Themas wird das %auch bei Formatierungsvorgängen für Zeichenfolgen verwendet, %=um Werte in eine Zeichenfolge zu ersetzen:

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

Wiederum kein Thema, aber es scheint ein wenig dokumentiertes Feature zu sein, das ich eine Weile gebraucht habe, um es aufzuspüren, und ich dachte, es hängt mit der Pythons-Modulo-Berechnung zusammen, für die diese SO-Seite einen hohen Stellenwert hat.


Gibt es eine Logik dafür, dass% auch als Referenz für die Zeichenfolgenformatierung verwendet wird, oder ist es nur ein Zufall in der Geschichte, dass dieses Symbol überladen wurde? Sollte dies seine eigene Frage sein?
WAF

5
Schlecht dokumentiert? Ich glaube nicht: String-Formatierungsoperationen
KurzedMetal

@KurzedMetal - %=erscheint nicht auf dieser Seite
P. Myer Nore

@WAF Der %Operator wurde ausgewählt, weil er die in der Zeichenfolge selbst verwendeten Prozentangaben widerspiegelt .
MI Wright

@ P.MyerNore Ich weiß, dass dies fast 3 Jahre später ist, kann aber anderen helfen. Lesen Sie den ersten hervorgehobenen Absatz in Sek. 5.6.2 oben von KurzedMetal verlinkt. Das "x% = {}" ist einfach eine Kurzform für "x = x% {...}"
Sujay Phadke

58

Ein Ausdruck wie wird x % yfür den Rest von x ÷ y- nun, technisch gesehen ist es "Modul" anstelle von "Erinnerung", sodass die Ergebnisse unterschiedlich sein können, wenn Sie mit anderen Sprachen vergleichen, in denen %sich der Restoperator befindet. Es gibt einige subtile Unterschiede (wenn Sie an den praktischen Konsequenzen interessiert sind, siehe auch "Warum Pythons Integer Division Floors" unten).

Die Priorität entspricht den Operatoren /(Division) und *(Multiplikation).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 geteilt durch 2 ist gleich 4.
  • 4 mal 2 ist 8
  • 9 minus 8 ist 1 - der Rest.

Python gotcha : Abhängig von der von Ihnen verwendeten Python-Version %ist dies auch der (veraltete) String-Interpolationsoperator. Achten Sie also darauf, ob Sie aus einer Sprache mit automatischer Typumwandlung (wie PHP oder JS) stammen, in der ein Ausdruck wie '12' % 2 + 3legal ist: in Python wird dazu führen, TypeError: not all arguments converted during string formattingwas für Sie wahrscheinlich ziemlich verwirrend sein wird.

[Update für Python 3]

Benutzer n00p Kommentare:

9/2 ist 4,5 in Python. Sie müssen eine ganzzahlige Division wie folgt durchführen: 9 // 2, wenn Python Ihnen mitteilen soll, wie viele ganze Objekte nach der Division übrig sind (4).

Um genau zu sein, war die Ganzzahldivision in Python 2 die Standardeinstellung (wohlgemerkt, diese Antwort ist älter als mein Junge, der bereits in der Schule ist und zu der Zeit 2.x Mainstream war):

$ 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

In modernen Python- 9 / 2Ergebnissen in der 4.5Tat:

$ 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

[aktualisieren]

Benutzer dahiya_boy fragte in der Kommentarsitzung:

Frage : Können Sie mir bitte erklären , warum -11 % 5 = 4- dahiya_boy

Das ist komisch, oder? Wenn Sie dies in JavaScript versuchen:

> -11 % 5
-1

Dies liegt daran, dass in JavaScript %der Operator "Rest" ist, während es in Python der Operator "Modul" (Clock Math) ist.

Sie können die Erklärung direkt von GvR erhalten :


Bearbeiten - dahiya_boy

In Java und iOS, -11 % 5 = -1in Python und Ruby -11 % 5 = 4.

Nun, die Hälfte des Grundes wird von Paulo Scardine erklärt , und der Rest der Erklärung ist hier unten

In Java und iOS, %gibt den Rest das bedeutet , wenn Sie teilen 11% 5 gibt Quotient = 2 and remainder = 1und -11% 5 gibt Quotient = -2 and remainder = -1.

Beispielcode in schnellem iOS.

Geben Sie hier die Bildbeschreibung ein

Aber wenn wir in Python darüber sprechen, gibt es einen Taktmodul. Und seine Arbeit mit der folgenden Formel

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

Das bedeutet,

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

So, mod(11,5) = 1

Und

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

So, mod(-11,5) = 4

Beispielcode in Python 3.0.

Geben Sie hier die Bildbeschreibung ein


Warum Pythons Integer Division Floors?

Ich wurde heute (erneut) gebeten zu erklären, warum die Ganzzahldivision in Python den Boden des Ergebnisses zurückgibt, anstatt wie C gegen Null abzuschneiden.

Für positive Zahlen gibt es keine Überraschung:

>>> 5//2
2

Wenn jedoch einer der Operanden negativ ist, ist das Ergebnis bodenständig, dh von Null weggerundet (in Richtung negative Unendlichkeit):

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

Dies stört einige Leute, aber es gibt einen guten mathematischen Grund. Die Ganzzahldivisionsoperation (//) und ihr Geschwister, die Modulooperation (%), passen zusammen und erfüllen eine schöne mathematische Beziehung (alle Variablen sind Ganzzahlen):

a/b = q with remainder r

so dass

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

(unter der Annahme, dass a und b> = 0 sind).

Wenn Sie möchten, dass sich die Beziehung für negatives a erstreckt (wobei b positiv bleibt), haben Sie zwei Möglichkeiten: Wenn Sie q gegen Null kürzen, wird r negativ, sodass sich die Invariante auf 0 <= abs (r) <ändert kann den Boden q gegen negative Unendlichkeit legen, und die Invariante bleibt 0 <= r <b. [Update: Para behoben]

In der mathematischen Zahlentheorie bevorzugen Mathematiker immer die letztere Wahl (siehe z . B. Wikipedia ). Für Python habe ich die gleiche Wahl getroffen, da es einige interessante Anwendungen der Modulo-Operation gibt, bei denen das Vorzeichen von a uninteressant ist. Nehmen Sie einen POSIX-Zeitstempel (Sekunden seit Anfang 1970) und wandeln Sie ihn in die Tageszeit um. Da ein Tag 24 * 3600 = 86400 Sekunden hat, ist diese Berechnung einfach t% 86400. Wenn wir jedoch die Zeiten vor 1970 mit negativen Zahlen ausdrücken würden, würde die Regel "Auf Null abschneiden" ein bedeutungsloses Ergebnis liefern! Mit der Grundregel funktioniert alles gut.

Andere Anwendungen, an die ich gedacht habe, sind Berechnungen von Pixelpositionen in Computergrafiken. Ich bin sicher, es gibt noch mehr.

Für das negative b dreht sich übrigens alles um und die Invariante wird:

0 >= r > b.

Warum macht C das nicht so? Wahrscheinlich hat die Hardware dies zum Zeitpunkt der Entwicklung von C nicht getan. Und die Hardware hat es wahrscheinlich nicht so gemacht, weil in der ältesten Hardware negative Zahlen als "Vorzeichen + Größe" dargestellt wurden und nicht als Komplementdarstellung der beiden, die heutzutage verwendet wird (zumindest für ganze Zahlen). Mein erster Computer war ein Control Data-Mainframe, der sowohl für Ganzzahlen als auch für Gleitkommazahlen verwendet wurde. Ein Muster von 60 Einsen bedeutete negative Null!

Tim Peters, der weiß, wo alle Gleitkomma-Skelette von Python vergraben sind, hat einige Bedenken hinsichtlich meines Wunsches geäußert, diese Regeln auf Gleitkomma-Modulo auszudehnen. Er hat wahrscheinlich recht; Die Regel "In Richtung negativer Unendlichkeit abschneiden" kann einen Präzisionsverlust für x% 1.0 verursachen, wenn x eine sehr kleine negative Zahl ist. Aber das reicht mir nicht, um das Integer-Modulo zu brechen, und // ist eng damit verbunden.

PS. Beachten Sie, dass ich // anstelle von / verwende - dies ist die Python 3-Syntax und in Python 2 auch zulässig, um hervorzuheben, dass Sie wissen, dass Sie die Ganzzahldivision aufrufen. Der Operator / in Python 2 ist nicht eindeutig, da er für zwei ganzzahlige Operanden ein anderes Ergebnis zurückgibt als für einen int und einen float oder zwei float. Aber das ist eine völlig andere Geschichte; siehe PEP 238.

Gepostet von Guido van Rossum um 09:49 Uhr


1
Außerdem help(divmod)dokumentiert die invariant q, r = divmod(x y) <==> q*y + r == x.
Chepner

49

Der Modul ist eine mathematische Operation, die manchmal als "Taktarithmetik" bezeichnet wird. Ich finde es irreführend und verwirrend, es einfach als Rest zu beschreiben, weil es den wahren Grund maskiert, warum es in der Informatik so häufig verwendet wird. Es wird wirklich verwendet, um Zyklen zu umwickeln.

Denken Sie an eine Uhr: Angenommen, Sie sehen eine Uhr in "militärischer" Zeit, wobei der Zeitbereich von 0:00 bis 23,59 reicht. Wenn Sie nun möchten, dass jeden Tag um Mitternacht etwas passiert, möchten Sie, dass der aktuelle Zeit-Mod 24 Null ist:

if (Stunde% 24 == 0):

Sie können sich alle Stunden in der Geschichte vorstellen, die sich immer wieder um einen Kreis von 24 Stunden drehen, und die aktuelle Stunde des Tages ist diese unendlich lange Zahl mod 24. Es ist ein viel tieferes Konzept als nur ein Rest, es ist ein mathematischer Weg mit Zyklen umzugehen und es ist sehr wichtig in der Informatik. Es wird auch zum Umschließen von Arrays verwendet, sodass Sie den Index erhöhen und den Modul verwenden können, um nach Erreichen des Endes des Arrays zum Anfang zurückzukehren.


1
So wird es in Python implementiert:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani


7

In den meisten Sprachen wird% für den Modul verwendet . Python ist keine Ausnahme.


11
Soweit ich sehen kann, ist Python insofern ungewöhnlich, als es% für den Modul verwendet. Fortran, C / C ++ und Java verwenden% als Rest. (Siehe stackoverflow.com/questions/13683563/… . Die Unterschiede bestehen darin, wie mit negativen und gebrochenen Werten umgegangen wird.) Die Sprachen, die eine Unterscheidung treffen (z. B. Ada, Haskell und Scheme), verwenden die Wörter "rem" und "mod". (oder "Rest" und "Modulo") statt%.
Jim Pivarski

5
Update: Ich habe diese großartige Tabelle mit Modulo / Rest-Operationen nach Sprache en.wikipedia.org/wiki/Modulo_operation gefunden . Python ist ungewöhnlich, aber nicht einzigartig (zum Beispiel teilen TCL und Lua Pythons Konvention).
Jim Pivarski

5

Der% Modulo-Operator kann auch zum Drucken von Zeichenfolgen (genau wie in C) verwendet werden, wie in Google https://developers.google.com/edu/python/strings definiert .

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

Dies scheint ein Thema zu sein, aber es wird sicherlich jemandem helfen.


4

x % yberechnet den Rest der Division xgeteilt durch, ywobei der Quotient eine ganze Zahl ist . Der Rest hat das Zeichen von y.


Auf Python 3 ergibt die Berechnung 6.75; Dies liegt daran, dass das /eine echte Division macht, keine ganzzahlige Division wie (standardmäßig) in Python 2. In Python 2 1 / 4gibt es 0, da das Ergebnis abgerundet ist.

Die Ganzzahldivision kann auch in Python 3 mit dem //Operator durchgeführt werden. Um die 7 als Ergebnis zu erhalten, können Sie Folgendes ausführen:

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

Sie können die Python-Stilunterteilung auch in Python 2 erhalten, indem Sie einfach die Zeile hinzufügen

from __future__ import division

als erste Quellcodezeile in jeder Quelldatei.


8
Denken Sie daran, Kinder #ist für Kommentare und //ist ein Operator.
Mike Causer

3

Der Moduloperator wird normalerweise für die Restteilung in Ganzzahlen verwendet, in Python jedoch für Gleitkommazahlen.

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

Der% (Modulo) -Operator ergibt den Rest aus der Division des ersten Arguments durch das zweite. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert. Ein Null-Rechts-Argument löst die ZeroDivisionError-Ausnahme aus. Die Argumente können Gleitkommazahlen sein, z. B. 3,14% 0,7 entspricht 0,34 (da 3,14 4 * 0,7 + 0,34 entspricht). Der Modulo-Operator liefert immer ein Ergebnis mit demselben Vorzeichen wie sein zweiter Operand (oder Null). Der Absolutwert des Ergebnisses ist streng kleiner als der Absolutwert des zweiten Operanden [2].


3

Es handelt sich um eine Modulo-Operation, es sei denn, es handelt sich um einen altmodischen Zeichenfolgenformatierungsoperator im C-Stil, nicht um eine Modulo-Operation . Siehe hier für Details. Sie werden viel davon im vorhandenen Code sehen.


3

Außerdem gibt es eine nützliche integrierte Funktion namens divmod:

divmod (a, b)

Nehmen Sie zwei (nicht komplexe) Zahlen als Argumente und geben Sie ein Zahlenpaar zurück, das aus ihrem Quotienten und dem Rest besteht, wenn Sie eine lange Division verwenden.


2

Beachten Sie, dass

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

Selbst mit den Klammern ergibt sich 6,75 anstelle von 7, wenn in Python 3.4 berechnet.


Und der Operator '/' ist auch nicht so einfach zu verstehen (python2.7): try ...

- 1/4

1 - 1/4

Dies ist hier etwas abseits des Themas, sollte aber bei der Bewertung des obigen Ausdrucks berücksichtigt werden :)


2
Wie würde das jemals 7 sein? Es vereinfacht sich (1)+(0)-(0.25)+(6).
J.Steve

1

Es war schwierig für mich, bestimmte Anwendungsfälle für die Verwendung von% online zu finden, z. B. warum die Teilung des gebrochenen Moduls oder der negativen Modulteilung zu der Antwort führt, die dies tut. Hoffe, dies hilft, Fragen wie diese zu klären:

Modulteilung Allgemein:

Die Modulteilung gibt den Rest einer mathematischen Teilungsoperation zurück. Es macht es wie folgt:

Angenommen, wir haben eine Dividende von 5 und einen Divisor von 2. Die folgende Divisionsoperation wäre (gleich x):

dividend = 5
divisor = 2

x = 5/2 
  1. Der erste Schritt bei der Modulberechnung besteht darin, eine ganzzahlige Division durchzuführen:

    x_int = 5 // 2 (Ganzzahldivision in Python verwendet doppelten Schrägstrich)

    x_int = 2

  2. Als nächstes wird die Ausgabe von x_int mit dem Divisor multipliziert:

    x_mult = x_int * divisor x_mult = 4

  3. Zuletzt wird die Dividende vom x_mult abgezogen

    Dividende - x_mult = 1

  4. Die Moduloperation gibt daher 1 zurück:

    5% 2 = 1

Anwendung, um den Modul auf einen Bruch anzuwenden

Example: 2 % 5 

Die Berechnung des Moduls bei Anwendung auf einen Bruch ist dieselbe wie oben; Es ist jedoch wichtig zu beachten, dass die Ganzzahldivision zu einem Wert von Null führt, wenn der Divisor größer als die Dividende ist:

dividend = 2 
divisor = 5

Die ganzzahlige Division ergibt 0, während die; Wenn daher Schritt 3 oben ausgeführt wird, wird der Wert der Dividende durchgeführt (von Null abgezogen):

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

Anwendung, um den Modul auf ein Negativ anzuwenden

Floor Division tritt auf, bei der der Wert der Integer Division auf den niedrigsten Integer-Wert abgerundet wird:

import math 

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

y = 1.1
math.floor = 1

Wenn Sie also eine ganzzahlige Division durchführen, erhalten Sie möglicherweise ein anderes Ergebnis als erwartet!

Das Anwenden der obigen Schritte auf die folgende Dividende und den Divisor veranschaulicht das Modulkonzept:

dividend: -5 
divisor: 2 

Schritt 1: Ganzzahlige Division anwenden

x_int = -5 // 2  = -3

Schritt 2: Multiplizieren Sie das Ergebnis der ganzzahligen Division mit dem Divisor

x_mult = x_int * 2 = -6

Schritt 3: Subtrahieren Sie die Dividende von der multiplizierten Variablen und beachten Sie das doppelte Negativ.

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

Deshalb:

-5 % 2 = 1

0

Der% (Modulo) -Operator ergibt den Rest aus der Division des ersten Arguments durch das zweite. Die numerischen Argumente werden zuerst in einen gemeinsamen Typ konvertiert.

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

Dies basiert auf der Priorität des Operators.


0

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

/ ist (in diesem Fall eine ganze Zahl) Division, also:

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



0

Modul - Teilt den linken Operanden durch den rechten Operanden und gibt den Rest zurück.

Wenn es hilft:

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

... und so weiter.


0

Ich habe festgestellt, dass der einfachste Weg, den Moduloperator (%) zu erfassen, die lange Teilung ist. Dies ist der Rest und kann nützlich sein, um eine gerade oder ungerade Zahl zu bestimmen:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

gibt den Rest einer Division nicht viel zu sehen
DeafaltCoder
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.