Python xrange - pourquoi le remplacer par range() ?

Denis Ribeiro .

1 novembre 2026

Le logo Python et le texte "RANGE() VS. XRANGE() IN PYTHON: A COMPREHENSIVE COMPARISON FOR BEGINNERS".

Un ancien script Python peut fonctionner parfaitement jusqu’au jour où xrange déclenche un NameError. Le terme python xrange renvoie à une fonction de Python 2, remplacée par range() en Python 3. Voici la différence concrète, les effets sur la mémoire et les bonnes pratiques pour adapter un code existant.

Ce qu’il faut retenir immédiatement

  • xrange() appartient à Python 2 et n’existe plus en Python 3.
  • En Python 3, range() reprend le comportement économe en mémoire de l’ancien xrange().
  • range(5) produit les valeurs de 0 à 4, car la borne finale est exclue.
  • Utilisez list(range(...)) uniquement lorsque vous avez réellement besoin d’une liste complète.
  • Un pas nul provoque une erreur, tandis qu’un pas mal orienté peut produire une séquence vide.

Pourquoi xrange existait dans Python 2

Dans Python 2, range() construisait immédiatement une liste complète d’entiers. Avec range(1000000), le programme préparait donc un million de valeurs avant même de commencer la boucle. Cette approche était simple, mais elle pouvait consommer beaucoup de mémoire.

xrange() a été conçu pour éviter cette allocation. Il renvoyait un objet capable de fournir les nombres au fur et à mesure de l’itération, sans stocker toute la séquence en mémoire. C’est ce qu’on appelle une évaluation paresseuse, ou lazy evaluation.

# Python 2
for i in xrange(5):
    print i

Le résultat était le même qu’avec une boucle utilisant range(), mais la gestion interne différait. Dans la pratique, xrange() était surtout utile pour les grandes boucles ou les traitements répétés. Pour quelques dizaines de valeurs, la différence restait généralement négligeable.

Ce qui a changé avec Python 3

Python 3 a supprimé xrange() et a donné à range() le comportement économe en mémoire qui caractérisait l’ancien outil. En clair, cette écriture moderne est normalement suffisante :

# Python 3
for i in range(5):
    print(i)

Dans Python 3, range(5) ne renvoie pas une liste, mais un objet range. Il conserve principalement les paramètres de la séquence, comme le début, la fin et le pas, puis calcule les valeurs lorsque le programme les demande.

Je vois souvent une confusion sur ce point. range() n’est pas un générateur au sens strict, car l’objet peut être parcouru plusieurs fois et prend en charge l’indexation. Il se comporte comme une séquence numérique compacte, pas comme une liste déjà remplie.

Version range() xrange()
Python 2 Crée une liste Crée une séquence économe en mémoire
Python 3 Crée un objet range économe en mémoire N’existe pas

Logo Python avec le texte

Comment utiliser range correctement

La syntaxe accepte une, deux ou trois valeurs. La borne stop n’est jamais incluse, détail qui explique une grande partie des erreurs de débutant.

range(stop)
range(start, stop)
range(start, stop, step)

Une seule valeur

list(range(5))
# [0, 1, 2, 3, 4]

Avec un seul argument, Python commence à zéro et s’arrête juste avant la valeur indiquée. Ainsi, range(1) contient uniquement 0, tandis que range(5) contient cinq nombres.

Un début et une fin

list(range(2, 6))
# [2, 3, 4, 5]

Cette forme est pratique pour parcourir un intervalle précis. Je recommande de vérifier mentalement la première et la dernière valeur avant d’exécuter la boucle, surtout lorsqu’un index sert à accéder à une liste.

Un pas personnalisé

list(range(0, 10, 2))
# [0, 2, 4, 6, 8]

Le troisième argument définit le pas. Un pas négatif permet de parcourir les valeurs en sens inverse :

list(range(5, 0, -1))
# [5, 4, 3, 2, 1]

Le pas ne peut jamais être égal à zéro. range(1, 5, 0) provoque une exception ValueError, car Python ne pourrait pas progresser dans la séquence.

Comment migrer un ancien code Python 2

Dans la majorité des cas, la migration est directe. Remplacez xrange() par range(), puis adaptez la syntaxe d’affichage si le programme utilise aussi Python 2.

# Ancien code
for i in xrange(10):
    print i

# Code Python 3
for i in range(10):
    print(i)

La différence devient importante lorsque l’ancien programme attendait explicitement une liste. En Python 3, il faut la demander clairement :

valeurs = list(range(10))
valeurs.append(10)

Un objet range n’est pas modifiable et ne possède pas les méthodes d’une liste, comme append() ou remove(). Mon conseil est simple : gardez range() pour parcourir une séquence et utilisez list(range()) uniquement si votre traitement doit modifier, trier ou sérialiser les valeurs.

Si vous maintenez temporairement une bibliothèque compatible avec Python 2 et Python 3, une couche de compatibilité peut être nécessaire. Mais pour un nouveau projet en 2026, conserver xrange() n’apporte généralement rien et complique les tests, le déploiement et la maintenance.

Range économise de la mémoire, mais pas tous les coûts

Un objet range occupe une quantité de mémoire réduite, même lorsqu’il représente un grand intervalle. C’est son principal avantage par rapport à une liste, mais cela ne signifie pas que le traitement devient instantané.

La boucle doit toujours exécuter son contenu pour chaque valeur. Si le corps effectue une requête réseau, une opération sur disque ou un calcul complexe, remplacer une liste par range() ne supprimera pas ce coût. Le gain porte surtout sur l’allocation initiale et la mémoire utilisée.

nombres = range(10_000_000)

for nombre in nombres:
    pass

Cette construction évite de créer immédiatement dix millions d’objets dans une liste. En revanche, écrire list(range(10_000_000)) annule cet avantage, puisque toutes les valeurs sont alors matérialisées en mémoire.

Autre détail utile, range() est réutilisable :

indices = range(3)

print(list(indices))
print(list(indices))

Les deux conversions fonctionnent. Cela le distingue d’un itérateur consommable une seule fois, même si, pour une simple boucle, cette nuance reste souvent invisible.

Les erreurs qui reviennent le plus souvent

Utiliser xrange en Python 3

for i in xrange(5):
    print(i)

Ce code provoque NameError: name 'xrange' is not defined. La correction normale consiste à écrire range(5).

Oublier que la fin est exclue

list(range(1, 5))
# [1, 2, 3, 4]

Pour inclure 5, utilisez range(1, 6). Cette règle est cohérente avec les tranches de listes et rend les calculs d’index plus sûrs.

Choisir un pas incompatible avec la direction

list(range(5, 1, 1))
# []

La séquence veut partir de 5 vers 1, mais le pas augmente la valeur. Il faut donc utiliser -1 :

list(range(5, 1, -1))
# [5, 4, 3, 2]

Lire aussi : Valeur absolue Python - abs() vs math.fabs() : Le guide complet

Confondre range et liste

range(4) ne permet pas d’ajouter directement un élément et son affichage peut surprendre :

valeurs = range(4)
print(valeurs)
# range(0, 4)

Si le programme attend la représentation [0, 1, 2, 3], convertissez explicitement l’objet avec list(valeurs). Cette conversion doit être un choix fonctionnel, pas un réflexe automatique.

Le bon réflexe pour les projets Python actuels

Pour du code Python 3, retenez une règle pratique : remplacez xrange() par range(), puis ne créez une liste que si votre logique en a besoin. Vous obtenez ainsi une syntaxe actuelle, une consommation mémoire maîtrisée et un code plus facile à lire.

La vraie question n’est donc plus de choisir entre range et xrange. Il faut plutôt déterminer si le programme doit parcourir une séquence compacte ou manipuler une collection complète. Dans la plupart des boucles, range() est le choix naturel, fiable et largement suffisant.

Questions fréquentes

xrange() appartient à Python 2 et n’existe plus en Python 3. Il faut généralement le remplacer par range(), qui reprend son fonctionnement économe en mémoire.
En Python 3, range() crée un objet compact qui calcule les valeurs au fil de l’itération, sans stocker toute la séquence. Utilisez list(range(...)) seulement si vous devez modifier, trier ou sérialiser les valeurs.
La syntaxe est range(start, stop, step), avec une borne finale exclue. Par exemple, list(range(5, 0, -1)) produit [5, 4, 3, 2, 1]. Le pas ne peut pas être nul et doit être cohérent avec la direction de la séquence.
Remplacez xrange() par range() et adaptez éventuellement l’affichage avec print(). Si l’ancien code attend une liste modifiable, utilisez explicitement list(range(...)), car un objet range ne possède pas de méthode comme append().
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

migration xrange range python 2 mémoire
Autor Denis Ribeiro
Denis Ribeiro
Je m'appelle Denis Ribeiro et j'ai quatre ans d'expérience dans le domaine de la technologie, en particulier dans les domaines du web, de l'intelligence artificielle, des réseaux et de la sécurité. Mon intérêt pour ces sujets a commencé dès mon plus jeune âge, lorsque j'ai découvert à quel point la technologie pouvait transformer notre quotidien. J'aime expliquer des concepts complexes de manière simple, afin d'aider mes lecteurs à mieux comprendre les enjeux actuels et futurs de notre monde numérique. Dans mes écrits, je m'efforce de fournir des informations utiles, précises et à jour. Je prends le temps de vérifier mes sources et de comparer les informations, tout en suivant les dernières tendances du secteur. Mon objectif est de rendre l'apprentissage accessible à tous, en organisant mes connaissances de manière claire et structurée, afin que chacun puisse naviguer avec confiance dans cet univers en constante évolution.
Commentaires (1)
  • H

    Hugo46

    02 novembre 2026

    ah ouais c'est vrai j'avais complètement oublié que `xrange()` ça existait avant, lol. du coup c'est cool que `range()` fasse le taf maintenant et soit économe en mémoire, c'est ez. merci pour le rappel, j'avais un peu la flemme de chercher ça 😅

Ajouter un commentaire