261 votes

Quel est le résultat de % en Python ?

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

Est-ce qu'il calcule un pourcentage du calcul par exemple : 4 % 2 est apparemment égal à 0. Comment ?

327voto

meder Points 81864

L'opérateur % (modulo) donne 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 de droite nul soulève 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 produit toujours un résultat avec le même signe que son second opérande (ou zéro) ; la valeur absolue du résultat est strictement inférieure à la valeur absolue du second opérande [2].

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

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

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

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

8 votes

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

9 votes

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

4 votes

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

147voto

mrmagooey Points 1170

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

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

Encore une fois, c'est hors sujet, mais il s'agit d'une fonctionnalité peu documentée qui m'a pris du temps à trouver, et Je pensais que c'était lié au calcul modulo de Python pour lequel cette page SO est très bien classée.

0 votes

Y a-t-il une logique à ce que % soit également utilisé comme référence pour le formatage des chaînes de caractères ou est-ce simplement un accident de l'histoire que ce symbole ait été surchargé ? Cette question devrait-elle avoir sa propre réponse ?

5 votes

Mal documenté ? Je ne le pense pas : Opérations de formatage des chaînes de caractères

0 votes

@KurzedMetal - %= n'apparaît pas sur cette page

61voto

Paulo Scardine Points 17518

Une expression comme x % y est évalué comme le reste de x ÷ y - bien, techniquement c'est "modulus" au lieu de "rappel" donc les résultats peuvent être différents si vous comparez avec d'autres langages où % est l'opérateur de reste. Il y a quelques différences subtiles (si vous êtes intéressé par les conséquences pratiques, voir aussi "Why Python's Integer Division Floors" ci-dessous).

La préséance est la même que celle des opérateurs / (division) et * (multiplication).

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

Le piège de Python : en fonction de la version de Python que vous utilisez, % est également l'opérateur (déprécié) d'interpolation de chaîne de caractères, donc faites attention si vous venez d'un langage avec un casting de type automatique (comme PHP ou JS) où une expression comme '12' % 2 + 3 est légal : en Python, il donnera lieu à TypeError: not all arguments converted during string formatting ce qui sera probablement assez déroutant pour vous.

[mise à jour pour Python 3]

Commentaires de l'utilisateur n00p :

9/2 est égal à 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 par défaut dans Python 2 (attention, cette réponse est plus ancienne que mon fils qui est déjà à l'école et à l'époque où les versions 2.x étaient courantes) :

$ 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

En Python moderne 9 / 2 résultats 4.5 en effet :

$ 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

[mise à jour]

L'utilisateur dahiya_boy a demandé dans 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

C'est parce qu'en JavaScript % est l'opérateur "reste" alors qu'en Python, c'est l'opérateur "modulus" (mathématique de l'horloge).

Vous pouvez obtenir l'explication directement de GvR :


Editer - dahiya_boy

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

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

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

Exemple de code en swift iOS.

enter image description here

Mais lorsque nous parlons en python, cela donne le module d'horloge. Et cela fonctionne avec la formule suivante

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

Ce qui veut dire,

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

Donc, mod(11,5) = 1

Et

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

Donc, mod(-11,5) = 4

Exemple de code en python 3.0.

enter image description here


Pourquoi la division d'entiers de Python échoue-t-elle ?

On m'a demandé (encore) aujourd'hui d'expliquer pourquoi la division d'entiers en Python renvoie le plancher du résultat au lieu de le tronquer vers zéro comme en 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 arrondi, c'est-à-dire qu'il s'éloigne de 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 d'un nombre entier (//) et sa sœur, l'opération modulo (%), vont ensemble et satisfont une belle relation mathématique (toutes les variables sont des nombres entiers) :

a/b = q with remainder r

de telle sorte 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 se transforme en 0 <= abs(r) < sinon, vous pouvez plancher q vers l'infini négatif, et l'invariant reste 0 <= r < b. [mise à jour : correction de ce paragraphe].

En théorie 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 existe des applications intéressantes de l'opération modulo où le signe de a est inintéressant. Prenons l'exemple d'un timestamp POSIX (secondes depuis le début de l'année 1970) que l'on transforme en heure du jour. Comme il y a 24*3600 = 86400 secondes dans un jour, ce calcul est simplement t % 86400. Mais si nous devions exprimer les temps avant 1970 en utilisant des nombres négatifs, la règle de la "troncature vers zéro" donnerait un résultat sans signification ! En utilisant la règle du plancher, tout s'arrange.

D'autres applications auxquelles j'ai pensé sont les calculs de la position des pixels en infographie. Je suis sûr qu'il y en a d'autres.

Pour un b négatif, d'ailleurs, tout s'inverse, et l'invariant devient :

0 >= r > b.

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

Tim Peters, qui sait où sont enterrés tous les squelettes en virgule flottante de Python, a exprimé quelques inquiétudes quant à mon désir d'étendre ces règles aux modulo en virgule flottante. Il a probablement raison ; la règle "truncate-towards-negative-infinity" peut causer une perte de précision pour x%1.0 lorsque x est un très petit nombre négatif. Mais cela ne suffit pas pour que je casse le modulo en nombres entiers, et // est étroitement lié à cela.

PS. Notez que j'utilise // au lieu de / -- c'est la syntaxe de Python 3, et c'est également autorisé dans Python 2 pour souligner que vous savez que vous invoquez une division entière. L'opérateur / dans Python 2 est ambigu, puisqu'il renvoie un résultat différent pour deux opérandes entiers que pour un int et un float ou deux floats. Mais il s'agit là d'une histoire totalement différente ; voir PEP 238.

Posté par Guido van Rossum à 9:49 AM

1 votes

Aussi, help(divmod) documente l'invariant q, r = divmod(x y) <==> q*y + r == x .

49voto

jarvis01123 Points 41

Le module est une opération mathématique, parfois décrite comme une "arithmétique d'horloge". Je trouve que le fait de le décrire comme un simple reste est trompeur et déroutant car il masque la véritable raison pour laquelle il est tant utilisé en informatique. Il est en fait utilisé pour envelopper les cycles.

Pensez à une horloge : Supposons que vous regardiez une horloge en heure "militaire", où la gamme des temps va de 0:00 à 23.59. Si vous vouliez que quelque chose se produise chaque jour à minuit, vous voudriez que le temps actuel mod 24 soit égal à zéro :

si (heure % 24 == 0) :

On peut penser que toutes les heures de l'histoire s'enroulent autour d'un cercle de 24 heures, encore et encore, et que l'heure actuelle du jour est ce nombre infiniment long mod 24. C'est un concept beaucoup plus profond qu'un simple reste, c'est une façon mathématique de traiter les cycles et c'est très important en informatique. Il est également utilisé pour envelopper les tableaux, ce qui vous permet d'augmenter l'indice et d'utiliser le module pour revenir au début après avoir atteint la fin du tableau.

1 votes

C'est ainsi qu'il est implémenté en Python : a % b = a - b * floor(a/b)

9voto

Halil Points 461

Python - Opérateurs de base
http://www.tutorialspoint.com/python/python_basic_operators.htm

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

a = 10 et b = 20

b % a = 0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X