Cursus
L’opérateur modulo (%) en Python est un opérateur arithmétique fondamental qui sert à déterminer le reste d’une division. Bien que simple en apparence, il joue un rôle clé dans de nombreux cas d’usage en programmation. De la vérification de la parité d’un nombre à la gestion de cycles dans des séquences, en passant par le calcul des années bissextiles, maîtriser l’opérateur modulo améliore considérablement vos capacités de résolution de problèmes en Python.
Comprendre l’opérateur modulo est essentiel, car on le retrouve souvent dans :
- L’identification des nombres pairs et impairs
- La boucle sur des éléments de manière cyclique
- La mise en œuvre de calculs en arithmétique modulaire
- Des applications concrètes comme le calcul de dates, la cryptographie et la logique de jeu.
Dans cet article, je vous propose un guide complet de l’utilisation de l’opérateur modulo en Python : sa syntaxe, son comportement selon les types numériques, ses cas d’usage et des exemples pratiques. Si vous débutez en Python, envisagez notre cours Introduction to Python.
Qu’est-ce que l’opérateur modulo en Python ?
L’opérateur modulo (%) calcule le reste de la division entre deux nombres. Étant donnés deux nombres a (dividende) et b (diviseur), l’opération modulo renvoie le reste lorsque a est divisé par b.
Fondements mathématiques
Le modulo trouve son origine dans l’arithmétique modulaire, un système d’arithmétique sur les entiers où les nombres « reviennent au début » après avoir atteint une certaine valeur (le module). On l’utilise largement en cryptographie, pour le hachage et dans les calculs cycliques.
Pensez à une horloge sur 12 heures : après 12, au lieu d’aller à 13, on revient à 1. C’est de l’arithmétique modulaire avec un module de 12 :
13 % 12 = 1, ce qui signifie que 13 heures correspondent à 1 heure au format 12 heures.
Syntaxe et utilisation de base du modulo en Python
En Python, la syntaxe de l’opérateur modulo est directe :
remainder = dividend % divisor
Voyons quelques exemples simples :
# Opérations modulo de base
print(7 % 3)
print(15 % 4)
print(20 % 5)
1
3
0
Lorsque nous divisons 7 par 3, on obtient 2 avec un reste de 1. L’opérateur modulo renvoie ce reste. De même, 15 divisé par 4 donne 3 avec un reste de 3, et 20 divisé par 5 donne exactement 4 sans reste.
Travailler avec des entiers
Maintenant que nous avons les bases, voyons comment le modulo se comporte avec les entiers.
Modulo avec des entiers positifs
C’est le cas d’usage le plus simple de l’opérateur modulo :
# Exemples avec des entiers positifs
print(10 % 3)
print(25 % 7)
print(100 % 10)
1
4
0
Dans ces exemples, on calcule le résultat en déterminant combien de fois le diviseur « rentre » dans le dividende, puis ce qu’il reste :
- 10 ÷ 3 = 3 reste 1, donc 10 % 3 = 1
- 25 ÷ 7 = 3 reste 4, donc 25 % 7 = 4
- 100 ÷ 10 = 10 reste 0, donc 100 % 10 = 0
Modulo avec des entiers négatifs
Le comportement devient plus intéressant avec les nombres négatifs. Python suit une règle précise : le résultat de a % b a toujours le même signe que b (le diviseur).
# Exemples avec des entiers négatifs
print(-10 % 3)
print(10 % -3)
print(-10 % -3)
2
-2
-1
Ces résultats peuvent sembler contre-intuitifs au premier abord, mais ils obéissent à une règle cohérente :
- Pour
-10 % 3: au lieu d’obtenir -1 (si l’on pense -10 ÷ 3 = -3 reste -1), Python renvoie 2. C’est parce que Python cherche une valeur entre 0 et 3 (exclu) qui, ajoutée à un multiple de 3, donne -10. La réponse est 2, car -12 + 2 = -10. - Pour
10 % -3: le résultat a le même signe que le diviseur (-3), donc on obtient -2. En effet, 10 = (-3) × (-4) + (-2). - Pour
-10 % -3: le résultat est -1, car -10 = (-3) × 3 + (-1).
Comprendre la gestion des nombres négatifs avec le modulo est crucial pour les calculs cycliques, comme :
- Implémenter des fonctions de hachage
- Résoudre des problèmes d’« horloge »
- Gérer des logiques d’indexation négative dans les listes
Utiliser le modulo avec des nombres à virgule flottante
L’opérateur modulo en Python ne se limite pas aux entiers : il fonctionne aussi avec les nombres à virgule flottante :
# Modulo avec des nombres à virgule flottante
print(7.5 % 2)
print(9.7 % 4.2)
print(5.0 % 0.2)
1.5
1.299999999999999
0.19999999999999973
Avec des flottants, le principe est le même : on renvoie le reste après division. Cependant, en raison du format de représentation des flottants en machine (IEEE 754), de légères erreurs d’arrondi peuvent survenir.
Par exemple, au lieu de 1.3, Python renvoie 1.299999999999999, et au lieu de 0.2, il renvoie 0.19999999999999973. Ces petites imprécisions sont courantes en arithmétique flottante et doivent être prises en compte pour des calculs nécessitant une grande précision.
Python propose aussi la fonction math.fmod() du module math comme alternative pour les opérations de modulo avec des flottants, avec un traitement parfois différent de certains cas limites :
import math
print(math.fmod(7.5, 2))
print(math.fmod(-7.5, 2))
# Comparaison avec l’opérateur modulo de Python
print(-7.5 % 2)
1.5
-1.5
0.5
La principale différence entre % et math.fmod() tient à la gestion des nombres négatifs. Alors que % garantit que le résultat a le même signe que le diviseur et renvoie une valeur dans l’intervalle [0, diviseur), math.fmod() conserve le signe du dividende. Cette distinction est importante lorsque le signe du reste a une incidence.
Quand utiliser % plutôt que math.fmod() ?
- Utilisez
%lorsque vous avez besoin d’un comportement de signe cohérent (p. ex. boucler dans un intervalle). - Utilisez
math.fmod()lorsque le signe du dividende doit être préservé, comme dans des simulations physiques ou des fonctions mathématiques.
Gérer les nombres négatifs avec le modulo Python
Comme on l’a vu plus haut, l’implémentation du modulo avec des nombres négatifs peut surprendre. Examinons ce comportement de manière plus systématique :
# Comprendre le motif avec les nombres négatifs
for i in range(-10, 11):
result = i % 3
print(f"{i} % 3 = {result}")
-10 % 3 = 2
-9 % 3 = 0
-8 % 3 = 1
-7 % 3 = 2
-6 % 3 = 0
-5 % 3 = 1
-4 % 3 = 2
-3 % 3 = 0
-2 % 3 = 1
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
5 % 3 = 2
6 % 3 = 0
7 % 3 = 1
8 % 3 = 2
9 % 3 = 0
10 % 3 = 1
Observez le motif : les résultats s’enchaînent 0 → 1 → 2 de façon répétée, que le dividende soit positif ou négatif. Cette régularité rend le modulo particulièrement utile pour les calculs cycliques, comme :
- La rotation d’indices dans des tableaux ou buffers circulaires
- La mise en correspondance de valeurs dans des fonctions périodiques (p. ex. calculs temporels)
La formule mathématique que suit Python pour le modulo est :
Import math
a % b = a - (b * math.floor(a / b))
Cela garantit que le résultat est toujours entre 0 et b (exclu) lorsque b est positif, ou entre b et 0 (exclu) lorsque b est négatif.
Résumé de l’opérateur modulo en Python
L’opérateur modulo (%) en Python calcule le reste d’une division. Il suit une formule mathématique cohérente :
a % b = a - (b * math.floor(a / b))
Règles clés du comportement du modulo en Python :
- Pour des diviseurs positifs (
b > 0) - Le résultat est toujours dans l’intervalle
[0, b)(inclusif en 0, exclusif enb). - Pour des diviseurs négatifs (
b < 0) - Le résultat est toujours dans l’intervalle
(b, 0](exclusif enb, inclusif en0). - Le reste adopte le même signe que
b(le diviseur). - Fonctionne avec les entiers et les flottants
- Avec des flottants,
%suit la même formule mais peut induire de légères erreurs d’arrondi liées à la précision des flottants. - Différence entre
%etmath.fmod() %garantit que le reste a le même signe que le diviseur.math.fmod(a, b)garantit que le reste a le même signe que le dividende.
Cas d’usage courants de l’opérateur modulo
Voyons quelques applications pratiques de l’opérateur modulo avec des exemples supplémentaires.
Vérifier si un nombre est pair ou impair
L’un des usages les plus courants du modulo est de déterminer si un nombre est pair ou impair :
def is_even(number):
return number % 2 == 0
def is_odd(number):
return number % 2 != 0
# Test des fonctions
numbers = [1, 2, -3, 4, -5, 6, 7]
for num in numbers:
if is_even(num):
print(f"{num} is even")
else:
print(f"{num} is odd")
1 is odd
2 is even
-3 is odd
4 is even
-5 is odd
6 is even
7 is odd
Cela fonctionne parce que les nombres pairs laissent un reste de 0 lorsqu’ils sont divisés par 2, tandis que les impairs laissent un reste de 1 ou -1.
Parcourir une séquence en boucle
Le modulo est idéal pour créer des comportements cycliques, par exemple pour alterner au sein d’une liste d’éléments :
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
def get_day(n):
# Obtenir le jour de la semaine pour le nième jour, où le jour 0 est Monday
return days[n % len(days)]
# En partant de Monday (jour 0), quel jour sera-t-on dans 10 jours ?
print(get_day(10)) # Output: "Thursday"
# Quel jour était-on il y a 15 jours depuis Monday ?
print(get_day(-15)) # Output: "Sunday"
Thursday
Sunday
Dans cet exemple, quelle que soit la grandeur (même négative) de n, la fonction renvoie toujours un jour valide de la semaine.
Calcul d’une année bissextile
Bien que le calcul implique plusieurs conditions, l’opérateur modulo est au cœur de l’algorithme :
Les années bissextiles suivent la règle suivante :
- Une année est bissextile si elle est divisible par 4.
- Mais si elle est divisible par 100, elle n’est pas bissextile.
- Sauf si elle est aussi divisible par 400 : dans ce cas, elle est bien bissextile.
def is_leap_year(year):
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
# Test de la fonction
years = [1900, 2000, 2004, 2020, 2023, 2024]
for year in years:
if is_leap_year(year):
print(f"{year} is a leap year")
else:
print(f"{year} is not a leap year")
1900 is not a leap year
2000 is a leap year
2004 is a leap year
2020 is a leap year
2023 is not a leap year
2024 is a leap year
Cela garantit l’application correcte des règles du calendrier grégorien.
Exemples pratiques d’utilisation du modulo en Python
Voici plusieurs façons d’utiliser l’opérateur modulo dans vos projets Python :
Utiliser le modulo dans des boucles
On recourt souvent au modulo dans les boucles pour effectuer des actions à intervalles réguliers :
# Afficher un message toutes les 5 itérations
for i in range(1, 11):
print(f"Processing item {i}", end=": ")
if i % 5 == 0:
print("Checkpoint reached!")
else:
print("Continuing...")
Processing item 1: Continuing...
Processing item 2: Continuing...
Processing item 3: Continuing...
Processing item 4: Continuing...
Processing item 5: Checkpoint reached!
Processing item 6: Continuing...
Processing item 7: Continuing...
Processing item 8: Continuing...
Processing item 9: Continuing...
Processing item 10: Checkpoint reached!
Ce schéma est utile pour le traitement par lots, le suivi de progression ou toute fonctionnalité à déclenchement périodique.
Modulo dans des applications réelles
Hachage de mots de passe
En cryptographie, l’arithmétique modulaire est fondamentale. Voici un exemple simplifié d’utilisation du modulo dans une fonction de hachage basique :
def simple_hash(text, modulus=1000000007):
"""A very simple hash function using modulo."""
hash_value = 0
for char in text:
# Combine the current hash with the character's Unicode code point
hash_value = (hash_value * 31 + ord(char)) % modulus
return hash_value
# Test with some strings
print(simple_hash("hello")) # Output a number between 0 and 1000000006
print(simple_hash("world"))
print(simple_hash("hello world"))
print(simple_hash("こんにちは"))
99162322
113318802
204910434
807637228
Ceci est un exemple très basique ; les fonctions de hachage cryptographiques réelles sont bien plus complexes. Le modulo garantit que la valeur de hachage reste dans un intervalle maîtrisé tout en conservant des propriétés utiles.
Calculs horaires
Le modulo est pratique pour les calculs de temps, par exemple pour convertir un grand nombre d’heures en format standard.
def convert_to_12_hour_format(hours):
return hours % 12 or 12 # Ensure 0 maps to 12
# Exemple
print(convert_to_12_hour_format(13)) # Output: 1
print(convert_to_12_hour_format(24)) # Output: 12
print(convert_to_12_hour_format(36)) # Output: 12
Ici, l’opérateur modulo effectue le bouclage des heures sur un format 12 heures.
Développement de jeux : système de tours multijoueur
Dans les jeux au tour par tour multijoueurs, on peut utiliser le modulo pour faire alterner les joueurs.
players = ["Alice", "Bob", "Charlie"]
turns = 10
for turn in range(turns):
current_player = players[turn % len(players)]
print(f"Turn {turn + 1}: {current_player}'s move")
Turn 1: Alice's move
Turn 2: Bob's move
Turn 3: Charlie's move
Turn 4: Alice's move
Turn 5: Bob's move
Turn 6: Charlie's move
Turn 7: Alice's move
Turn 8: Bob's move
Turn 9: Charlie's move
Turn 10: Alice's move
Validation de chiffres dans les codes-barres
Beaucoup de systèmes de code-barres utilisent le modulo pour détecter des erreurs lors de la lecture des numéros.
def is_valid_isbn13(isbn):
digits = [int(d) for d in str(isbn)]
checksum = sum(d * (1 if i % 2 == 0 else 3) for i, d in enumerate(digits))
return checksum % 10 == 0
# Exemple de validation de checksum ISBN
print(is_valid_isbn13(9780306406157)) # Output: True
print(is_valid_isbn13(9780306406158)) # Output: False
True
False
Conclusion
L’opérateur modulo est un outil polyvalent de l’arsenal Python, bien au-delà du simple calcul de restes. De la détermination pair/impair à l’implémentation d’algorithmes complexes à motifs cycliques, il permet des solutions plus propres et élégantes à de nombreux défis de programmation.
En comprenant à la fois son fonctionnement de base et ses subtilités selon les types numériques, vous pourrez tirer parti du modulo pour écrire un code plus efficace et plus lisible. La prochaine fois que vous aurez à gérer des cycles, des rotations ou des événements périodiques, pensez que l’opérateur modulo est peut-être la solution idéale.
Si vous souhaitez approfondir l’utilisation de Python dans vos projets, découvrez notre cours interactif Introduction to Data Science in Python.
FAQ sur le modulo en Python
Comment l’opérateur modulo se comporte-t-il avec des nombres négatifs en Python ?
En Python, avec des nombres négatifs, le résultat de l’opération modulo a le même signe que le diviseur.
Peut-on utiliser l’opérateur modulo avec des nombres à virgule flottante ?
Oui, l’opérateur modulo fonctionne avec des nombres à virgule flottante, mais attention à de petites erreurs d’arrondi dues à leur représentation en machine.
Comment l’opérateur modulo est-il utilisé dans des applications réelles ?
L’opérateur modulo est utilisé dans de nombreuses applications concrètes, comme les fonctions de hachage, les calculs d’heure et la détection d’erreurs (ex. : validation ISBN).
Pourquoi l’opérateur modulo est-il important en programmation ?
Le modulo est crucial pour résoudre des problèmes impliquant périodicité, division et « retour au début », ce qui en fait un outil polyvalent pour coder efficacement et concevoir des algorithmes.
En tant que fondateur de Martin Data Solutions et Data Scientist freelance, ingénieur ML et AI, j'apporte un portefeuille diversifié en régression, classification, NLP, LLM, RAG, réseaux neuronaux, méthodes d'ensemble et vision par ordinateur.
- A développé avec succès plusieurs projets de ML de bout en bout, y compris le nettoyage des données, l'analyse, la modélisation et le déploiement sur AWS et GCP, en fournissant des solutions impactantes et évolutives.
- Création d'applications web interactives et évolutives à l'aide de Streamlit et Gradio pour divers cas d'utilisation dans l'industrie.
- Enseigne et encadre des étudiants en science des données et en analyse, en favorisant leur développement professionnel par le biais d'approches d'apprentissage personnalisées.
- Conception du contenu des cours pour les applications de génération augmentée par récupération (RAG) adaptées aux exigences de l'entreprise.
- Rédaction de blogs techniques à fort impact sur l'IA et le ML, couvrant des sujets tels que les MLOps, les bases de données vectorielles et les LLM, avec un engagement significatif.
Dans chaque projet que je prends en charge, je m'assure d'appliquer des pratiques actualisées en matière d'ingénierie logicielle et de DevOps, comme le CI/CD, le linting de code, le formatage, la surveillance des modèles, le suivi des expériences et la gestion robuste des erreurs. Je m'engage à fournir des solutions complètes, en transformant les connaissances sur les données en stratégies pratiques qui aident les entreprises à se développer et à tirer le meilleur parti de la science des données, de l'apprentissage automatique et de l'IA.
