Quel est le résultat de% en Python?


241

Que fait le %dans un calcul? Je n'arrive pas à comprendre ce qu'il fait.

Est-ce que cela fonctionne par exemple un pourcentage du calcul: 4 % 2est apparemment égal à 0. Comment?

Réponses:


304

L'opérateur% (modulo) produit le reste de la division du premier argument par le second. Les arguments numériques sont d'abord convertis en un type commun. Un argument zéro à droite déclenche l'exception ZeroDivisionError. Les arguments peuvent être des nombres à virgule flottante, par exemple, 3,14% 0,7 est égal à 0,34 (puisque 3,14 est égal à 4 * 0,7 + 0,34). L'opérateur modulo donne toujours un résultat avec le même signe que son deuxième opérande (ou zéro); la valeur absolue du résultat est strictement inférieure à la valeur absolue du deuxième opérande [2].

Tiré de http://docs.python.org/reference/expressions.html

Exemple 1: 6%2 évalue à 0car il n'y a pas de reste si 6 est divisé par 2 (3 fois).

Exemple 2 : 7%2évalue à 1car il y a un reste 1lorsque 7 est divisé par 2 (3 fois).

Donc pour résumer cela, il renvoie le reste d'une opération de division, ou 0s'il n'y a pas de reste. Cela 6%2signifie donc trouver le reste de 6 divisé par 2.


7
Pourquoi tous les exemples ont-ils un plus grand nombre à droite? Quelqu'un peut-il expliquer le résultat de 2% 6 qui donne 2?
wookie

8
Le premier chiffre est le numérateur et le second le dénominateur. Dans votre exemple 2 divisé par 6 est 0 reste 2, donc le résultat est 2.
David

4
Veuillez mettre à jour votre réponse, il y a des réponses plus précises ci-dessous. En C / C ++ % est pour «rem» alors qu'en Python% est pour «mod». par exemple - 21 % 4est 3 en Python.
azam

Pouvez-vous expliquer pourquoi -11%5 = 4?
dahiya_boy

@dahiya_boy J'ai ajouté l'explication de GvR à ma réponse moins positive ci-dessous.
Paulo Scardine

143

Un peu hors sujet, le %est également utilisé dans les opérations de formatage de chaînes, comme %=pour remplacer des valeurs dans une chaîne:

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

Encore une fois, hors sujet, mais cela semble être une fonctionnalité peu documentée qui m'a pris un certain temps à retrouver, et je pensais que c'était lié au calcul modulo de Pythons pour lequel cette page SO se classe très bien.


Y a-t-il une logique pour que% soit également utilisé comme référence de formatage de chaîne ou est-ce simplement un accident de l'histoire que ce symbole a été surchargé? Cela devrait-il être sa propre question?
WAF

5
Mal documenté? Je ne pense pas: Opérations de formatage de chaînes
KurzedMetal

@KurzedMetal - %=n'apparaît pas sur cette page
P. Myer Nore

@WAF L' %opérateur a été choisi car il reflète les pourcentages-spécificateurs utilisés dans la chaîne elle-même.
MI Wright

@ P.MyerNore Je sais que c'est presque 3 ans plus tard, mais cela peut aider les autres. Lisez le premier paragraphe surligné en sec. 5.6.2 lié ci-dessus par KurzedMetal. Le "x% = {}" est simplement un raccourci pour "x = x% {...}"
Sujay Phadke

58

Une expression comme x % yévalue le reste de x ÷ y- eh bien, techniquement, c'est "module" au lieu de "rappel", donc les résultats peuvent être différents si vous comparez avec d'autres langues où se %trouve l'opérateur restant. Il y a quelques différences subtiles (si vous êtes intéressé par les conséquences pratiques, voir également "Pourquoi les étages de division entiers de Python" ci-dessous).

La priorité est la même que pour les opérateurs /(division) et *(multiplication).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 divisé par 2 est égal à 4.
  • 4 fois 2 est 8
  • 9 moins 8 est 1 - le reste.

Python gotcha : selon la version Python que vous utilisez, %est également l'opérateur d'interpolation de chaîne (obsolète), alors faites attention si vous venez d'un langage avec une conversion automatique de type (comme PHP ou JS) où une expression comme '12' % 2 + 3est légale: dans Python, il en résultera TypeError: not all arguments converted during string formattingqui sera probablement assez déroutant pour vous.

[mise à jour pour Python 3]

Commentaires de l'utilisateur n00p:

9/2 est 4,5 en python. Vous devez faire une division entière comme ceci: 9 // 2 si vous voulez que python vous dise combien d'objets entiers il reste après la division (4).

Pour être précis, la division entière était la valeur par défaut dans Python 2 (rappelez-vous, cette réponse est plus ancienne que mon garçon qui était déjà à l'école et à l'époque 2.x étaient traditionnels):

$ 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

Dans les 9 / 2résultats Python modernes en 4.5effet:

$ 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

[mettre à jour]

L'utilisateur dahiya_boy a demandé lors de la session de commentaires:

Q. Pouvez-vous expliquer pourquoi -11 % 5 = 4- dahiya_boy

C'est bizarre, non? Si vous essayez ceci en JavaScript:

> -11 % 5
-1

En effet, en JavaScript %est l'opérateur "reste" tandis qu'en Python c'est l'opérateur "module" (calcul d'horloge).

Vous pouvez obtenir l'explication directement auprès de GvR :


Modifier - dahiya_boy

En Java et iOS -11 % 5 = -1alors qu'en python et rubis -11 % 5 = 4.

Eh bien la moitié de la raison est expliquée par le Paulo Scardine , et le reste de l'explication est ci-dessous ici

En Java et iOS, %donne le reste, ce qui signifie que si vous divisez 11% 5 donne Quotient = 2 and remainder = 1et -11% 5 donne Quotient = -2 and remainder = -1.

Exemple de code dans iOS rapide.

entrez la description de l'image ici

Mais quand on parle de python, cela donne un module d'horloge. Et son travail avec la formule ci-dessous

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

Cela signifie,

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

Alors, mod(11,5) = 1

Et

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

Alors, mod(-11,5) = 4

Exemple de code en python 3.0.

entrez la description de l'image ici


Pourquoi les étages de la division entière de Python

On m'a demandé (encore) aujourd'hui d'expliquer pourquoi la division entière en Python renvoie le plancher du résultat au lieu de tronquer vers zéro comme C.

Pour les chiffres positifs, il n'y a pas de surprise:

>>> 5//2
2

Mais si l'un des opérandes est négatif, le résultat est plancher, c'est-à-dire arrondi à zéro (vers l'infini négatif):

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

Cela dérange certaines personnes, mais il y a une bonne raison mathématique. L'opération de division entière (//) et son frère, l'opération modulo (%), vont ensemble et satisfont une belle relation mathématique (toutes les variables sont des entiers):

a/b = q with remainder r

tel que

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

(en supposant que a et b sont> = 0).

Si vous voulez que la relation s'étende pour a négatif (en gardant b positif), vous avez deux choix: si vous tronquez q vers zéro, r deviendra négatif, de sorte que l'invariant passe à 0 <= abs (r) <sinon, vous peut plancher q vers l'infini négatif, et l'invariant reste 0 <= r <b. [mise à jour: correction de ce para]

Dans la théorie mathématique des nombres, les mathématiciens préfèrent toujours ce dernier choix (voir par exemple Wikipedia ). Pour Python, j'ai fait le même choix car il y a des applications intéressantes de l'opération modulo où le signe d'un n'est pas intéressant. Pensez à prendre un horodatage POSIX (secondes depuis le début de 1970) et à le transformer en heure du jour. Puisqu'il y a 24 * 3600 = 86400 secondes dans une journée, ce calcul est simplement t% 86400. Mais si nous devions exprimer des temps avant 1970 en utilisant des nombres négatifs, la règle "tronquer vers zéro" donnerait un résultat dénué de sens! En utilisant la règle du plancher, tout fonctionne bien.

Les autres applications auxquelles j'ai pensé sont les calculs de positions de pixels en infographie. Je suis sûr qu'il y en a plus.

Pour le négatif b, au fait, tout bascule et l'invariant devient:

0 >= r > b.

Alors pourquoi C ne le fait-il pas de cette façon? Le matériel n'a probablement pas fait cela au moment où C a été conçu. Et le matériel ne l'a probablement pas fait de cette façon parce que dans le matériel le plus ancien, les nombres négatifs étaient représentés par "signe + amplitude" plutôt que par la représentation du complément à deux utilisée de nos jours (au moins pour les entiers). Mon premier ordinateur était un ordinateur central Control Data et il utilisait son complément pour les entiers ainsi que pour les flottants. Un motif de 60 unités signifiait zéro négatif!

Tim Peters, qui sait où tous les squelettes à virgule flottante de Python sont enterrés, a exprimé une certaine inquiétude quant à mon désir d'étendre ces règles au modulo à virgule flottante. Il a probablement raison; la règle de troncature vers l'infini négatif peut entraîner une perte de précision pour x% 1.0 lorsque x est un très petit nombre négatif. Mais cela ne me suffit pas pour casser le modulo entier, et // est étroitement lié à cela.

PS. Notez que j'utilise // au lieu de / - c'est la syntaxe Python 3, et également autorisée en Python 2 pour souligner que vous savez que vous invoquez la division entière. L'opérateur / en Python 2 est ambigu, car il renvoie un résultat différent pour deux opérandes entiers que pour un int et un flottant ou deux flottants. Mais c'est une histoire totalement distincte; voir PEP 238.

Publié par Guido van Rossum à 09 h 49


1
En outre, help(divmod)documente l'invariant q, r = divmod(x y) <==> q*y + r == x.
chepner

49

Le module est une opération mathématique, parfois appelée "arithmétique d'horloge". Je trouve que le décrire simplement comme un reste est trompeur et déroutant car il masque la vraie raison pour laquelle il est tellement utilisé en informatique. Il est vraiment utilisé pour boucler les cycles.

Pensez à une horloge: supposons que vous regardiez une horloge en temps "militaire", où la plage de temps va de 0:00 à 23.59. Maintenant, si vous vouliez que quelque chose se produise tous les jours à minuit, vous voudriez que l'heure actuelle mod 24 soit zéro:

si (heure% 24 == 0):

Vous pouvez penser à toutes les heures de l'histoire qui tournent autour d'un cercle de 24 heures et plus et l'heure actuelle du jour est ce nombre infiniment long mod 24. C'est un concept beaucoup plus profond que juste un reste, c'est une manière mathématique pour gérer les cycles et c'est très important en informatique. Il est également utilisé pour envelopper les tableaux, vous permettant d'augmenter l'index et d'utiliser le module pour revenir au début après avoir atteint la fin du tableau.


1
Voici comment il est implémenté en Python:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani


7

Dans la plupart des langues,% est utilisé pour le module . Python ne fait pas exception.


11
Pour autant que je puisse voir, Python est inhabituel en ce qu'il utilise% pour le module; Fortran, C / C ++ et Java utilisent% pour signifier le reste. (Voir stackoverflow.com/questions/13683563/… , les différences sont dans la façon dont les valeurs négatives et fractionnaires sont gérées.) Les langages qui font une distinction (par exemple Ada, Haskell et Scheme) utilisent les mots "rem" et "mod" (ou "reste" et "modulo") plutôt que%.
Jim Pivarski

5
Mise à jour: J'ai trouvé ce grand tableau des opérations modulo / reste par langue en.wikipedia.org/wiki/Modulo_operation . Python est inhabituel mais pas unique (par exemple, TCL et Lua partagent la convention de Python.)
Jim Pivarski

5

L'opérateur% Modulo peut également être utilisé pour imprimer des chaînes (comme en C) comme défini sur 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')

Cela semble un peu hors sujet, mais cela aidera certainement quelqu'un.


4

x % ycalcule le reste de la division xdivisé par yle quotient est un entier . Le reste a le signe de y.


Sur Python 3, le calcul donne 6.75; c'est parce que le /fait une vraie division, pas une division entière comme (par défaut) sur Python 2. Sur Python 2 1 / 4donne 0, car le résultat est arrondi.

La division entière peut également être effectuée sur Python 3, avec l' //opérateur, donc pour obtenir le 7 en conséquence, vous pouvez exécuter:

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

En outre, vous pouvez obtenir la division de style Python sur Python 2, en ajoutant simplement la ligne

from __future__ import division

comme première ligne de code source dans chaque fichier source.


8
N'oubliez pas que les enfants #sont des commentaires et //sont un opérateur.
Mike Causer

3

Opérateur de module, il est utilisé pour la division du reste sur les entiers, généralement, mais en Python peut être utilisé pour les nombres à virgule flottante.

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

L'opérateur% (modulo) produit le reste de la division du premier argument par le second. Les arguments numériques sont d'abord convertis en un type commun. Un argument zéro à droite déclenche l'exception ZeroDivisionError. Les arguments peuvent être des nombres à virgule flottante, par exemple, 3,14% 0,7 est égal à 0,34 (puisque 3,14 est égal à 4 * 0,7 + 0,34). L'opérateur modulo donne toujours un résultat avec le même signe que son deuxième opérande (ou zéro); la valeur absolue du résultat est strictement inférieure à la valeur absolue du deuxième opérande [2].


3

Il s'agit d'une opération modulo, sauf lorsqu'il s'agit d'un opérateur de formatage de chaîne de style C à l'ancienne, et non d'une opération modulo . Voir ici pour plus de détails. Vous verrez beaucoup de cela dans le code existant.


3

En outre, il existe une fonction intégrée utile appelée divmod:

divmod (a, b)

Prenez deux nombres (non complexes) comme arguments et renvoyez une paire de nombres comprenant leur quotient et le reste lors de l'utilisation d'une division longue.


2

Soit conscient que

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

même avec les crochets donne 6,75 au lieu de 7 si calculé en Python 3.4.


Et l'opérateur '/' n'est pas aussi simple à comprendre (python2.7): essayez ...

- 1/4

1 - 1/4

Ceci est un peu hors sujet ici, mais devrait être pris en compte lors de l'évaluation de l'expression ci-dessus :)


2
Comment serait-ce jamais 7? Il simplifie (1)+(0)-(0.25)+(6).
J.Steve

1

Il était difficile pour moi de trouver facilement des cas d'utilisation spécifiques pour l'utilisation de% en ligne, par exemple, pourquoi la division de module fractionnaire ou la division de module négative donne-t-elle la réponse qu'elle fait. J'espère que cela aide à clarifier des questions comme celle-ci:

Division du module en général:

La division de module renvoie le reste d'une opération de division mathématique. Il le fait comme suit:

Supposons que nous ayons un dividende de 5 et un diviseur de 2, l'opération de division suivante serait (équivalente à x):

dividend = 5
divisor = 2

x = 5/2 
  1. La première étape du calcul du module consiste à effectuer une division entière:

    x_int = 5 // 2 (la division entière en python utilise une double barre oblique)

    x_int = 2

  2. Ensuite, la sortie de x_int est multipliée par le diviseur:

    x_mult = x_int * diviseur x_mult = 4

  3. Enfin, le dividende est soustrait du x_mult

    dividende - x_mult = 1

  4. L'opération de module renvoie donc 1:

    5% 2 = 1

Application pour appliquer le module à une fraction

Example: 2 % 5 

Le calcul du module appliqué à une fraction est le même que ci-dessus; cependant, il est important de noter que la division entière entraînera une valeur de zéro lorsque le diviseur est supérieur au dividende:

dividend = 2 
divisor = 5

La division entière donne 0 alors que le; par conséquent, lorsque l'étape 3 ci-dessus est effectuée, la valeur du dividende est appliquée (soustraite de zéro):

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

Application pour appliquer le module à un négatif

La division du sol se produit dans laquelle la valeur de la division entière est arrondie à la valeur entière la plus basse:

import math 

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

y = 1.1
math.floor = 1

Par conséquent, lorsque vous effectuez une division entière, vous pouvez obtenir un résultat différent de celui auquel vous vous attendez!

L'application des étapes ci-dessus sur le dividende et le diviseur suivants illustre le concept de module:

dividend: -5 
divisor: 2 

Étape 1: appliquer la division entière

x_int = -5 // 2  = -3

Étape 2: Multipliez le résultat de la division entière par le diviseur

x_mult = x_int * 2 = -6

Étape 3: Soustrayez le dividende de la variable multipliée, notez le double négatif.

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

Par conséquent:

-5 % 2 = 1

0

L'opérateur% (modulo) produit le reste de la division du premier argument par le second. Les arguments numériques sont d'abord convertis en un type commun.

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

Ceci est basé sur la priorité de l'opérateur.


0

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

/ est (un entier dans ce cas) une division, donc:

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



0

Module - Divise l'opérande de gauche par l'opérande de droite et renvoie le reste.

Si cela aide:

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

... etc.


0

J'ai trouvé que la façon la plus simple de saisir l'opérateur de module (%) est de passer par une longue division. C'est le reste et peut être utile pour déterminer un nombre pair ou impair:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

ne donne pas grand-chose au reste d'une division
DeafaltCoder
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.