La fonction range () de Python (Guide)

La fonction range () de Python (Guide)

La fonctionrange intégrée de Python est pratique lorsque vous devez effectuer une action un certain nombre de fois. En tant que Pythonista expérimenté, vous l'avez probablement déjà utilisé auparavant. Mais qu'est-ce que ça fait?

À la fin de ce guide, vous allez:

  • Comprendre le fonctionnement de la fonction Pythonrange

  • Savoir comment les implémentations diffèrent dans Python 2 et Python 3

  • J'ai vu un certain nombre d'exemples pratiques derange()

  • Être équipé pour contourner certaines de ses limites

Allons craquer!

Free Bonus:Click here to get our free Python Cheat Sheet qui vous montre les bases de Python 3, comme travailler avec des types de données, des dictionnaires, des listes et des fonctions Python.

L’histoire de la fonctionrange() de Python

Bien querange() en Python 2 etrange() en Python 3 puissent partager un nom, ce sont des animaux totalement différents. En fait,range() dans Python 3 n'est qu'une version renommée d'une fonction appeléexrange dans Python 2.

À l'origine,range() etxrange() produisaient des nombres qui pouvaient être itérés avec des boucles for, mais le premier générait une liste de ces nombres en même temps tandis que le second produisait des nombreslazily, ce qui signifie les numéros étaient retournés un par un au fur et à mesure des besoins.

Avoir d'énormes listes qui traînent prend de la mémoire, il n'est donc pas surprenant quexrange() ait remplacérange(), nom et tout. Vous pouvez en savoir plus sur cette décision et sur le contexte dexrange() vsrange() dansPEP 3100.

Note: PEP signifie Python Enhancement Proposition. Les PPE sont des documents qui peuvent couvrir un large éventail de sujets, y compris les nouvelles fonctionnalités proposées, le style, la gouvernance et la philosophie.

Il y aa ton of them. PEP 1 explique comment ils fonctionnent et constitue un excellent point de départ.

Pour le reste de cet article, vous utiliserez la fonction telle qu'elle existe dans Python 3.

Et c'est parti!

Boucle

Avant de nous plonger dans le fonctionnement derange(), nous devons examiner le fonctionnement de la boucle. Le bouclage est unkey computer science concept. Si vous voulez être un bon programmeur, la maîtrise des boucles fait partie des premières étapes à suivre.

Voici un exemple de boucle for en Python:

captains = ['Janeway', 'Picard', 'Sisko']

for captain in captains:
    print(captain)

La sortie ressemble à ceci:

Janeway
Picard
Sisko

Comme vous pouvez le voir, une boucle for vous permet d'exécuter un bloc de code spécifique autant de fois que vous le souhaitez. Dans ce cas, nous avons parcouru une liste de capitaines et imprimé chacun de leurs noms.

Bien que Star Trek soit génial et tout, vous voudrez peut-être faire plus que simplement parcourir une liste de capitaines. Parfois, vous souhaitez simplement exécuter un bloc de code un certain nombre de fois. Les boucles peuvent vous y aider!

Essayez le code suivant avec des nombres divisibles par trois:

numbers_divisible_by_three = [3, 6, 9, 12, 15]

for num in numbers_divisible_by_three:
    quotient = num / 3
    print(f"{num} divided by 3 is {int(quotient)}.")

La sortie de cette boucle ressemblera à ceci:

3 divided by 3 is 1.
6 divided by 3 is 2.
9 divided by 3 is 3.
12 divided by 3 is 4.
15 divided by 3 is 5.

C’est la sortie que nous voulions, donc la boucle a fait le travail correctement, mais il existe un autre moyen d’obtenir le même résultat en utilisantrange().

Note: Ce dernier exemple de code avait un formatage de chaîne. Pour en savoir plus sur ce sujet, vous pouvez consulterPython String Formatting Best Practices etPython 3’s f-Strings: An Improved String Formatting Syntax (Guide).

Maintenant que vous êtes plus familier avec les boucles, voyons comment vous pouvez utiliserrange() pour vous simplifier la vie.

Principes de base de Pythonrange()

Alors, comment fonctionne la fonctionrange de Python? En termes simples,range() vous permet de générer une série de nombres dans une plage donnée. Selon le nombre d'arguments que vous passez à la fonction, vous pouvez décider du début et de la fin de cette série de nombres ainsi que de l'ampleur de la différence entre un nombre et le suivant.

Voici un aperçu derange() en action:

for i in range(3, 16, 3):
    quotient = i / 3
    print(f"{i} divided by 3 is {int(quotient)}.")

Dans cette boucle for, vous avez simplement pu créer une plage de nombres qui sont divisibles par3, vous n'avez donc pas besoin de fournir chacun d'eux vous-même.

Note: Bien que cet exemple montre une utilisation appropriée derange(), il est généralement désapprouvé d'utiliser trop souventrange() dans les boucles for.

Par exemple, l'utilisation suivante derange() serait généralement considérée comme non pythonique:

captains = ['Janeway', 'Picard', 'Sisko']

for i in range(len(captains)):
    print(captains[i])

range() est idéal pour créer des itérables de nombres, mais ce n'est pas le meilleur choix lorsque vous avez besoin d'itérer sur des données qui pourraient être bouclées avec lesin operator.

Si vous voulez en savoir plus, consultezHow to Make Your Python Loops More Pythonic.

Il existe trois façons d'appelerrange():

  1. range(stop) prend un argument.

  2. range(start, stop) prend deux arguments.

  3. range(start, stop, step) prend trois arguments.

range(stop)

Lorsque vous appelezrange() avec un argument, vous obtiendrez une série de nombres commençant à0 et incluant tous les nombres entiers jusqu'à, mais non compris, le nombre que vous avez fourni commestop.

Voici à quoi cela ressemble en pratique:

for i in range(3):
    print(i)

La sortie de votre boucle ressemblera à ceci:

0
1
2

Cela vérifie: nous avons tous les nombres entiers de0 jusqu'à mais non compris3, le nombre que vous avez fourni commestop.

range(start, stop)

Lorsque vous appelezrange() avec deux arguments, vous décidez non seulement où s'arrête la série de nombres, mais aussi où elle commence, de sorte que vous n'avez pas à commencer à0 tout le temps. Vous pouvez utiliserrange() pour générer une série de nombres deA àB en utilisant unrange(A, B). Voyons comment générer une plage commençant à1.

Essayez d'appelerrange() avec deux arguments:

for i in range(1, 8):
    print(i)

Votre sortie ressemblera à ceci:

1
2
3
4
5
6
7

Jusqu'à présent, tout va bien: vous avez tous les nombres entiers de1 (le nombre que vous avez fourni en tant questart) jusqu'à mais non compris8 (le nombre que vous avez fourni commestop).

Mais si vous ajoutez un autre argument, vous pourrez reproduire la sortie que vous avez obtenue précédemment lorsque vous utilisiez la liste nomméenumbers_divisible_by_three.

range(start, stop, step)

Lorsque vous appelezrange() avec trois arguments, vous pouvez non seulement choisir où la série de nombres commencera et s'arrêtera, mais aussi quelle sera la différence entre un nombre et le suivant. Si vous ne fournissez pas destep, alorsrange() se comportera automatiquement comme si lestep était1.

Note:step peut être un nombre positif ou négatif, mais ce ne peut pas être0:

>>>

>>> range(1, 4, 0)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: range() arg 3 must not be zero

Si vous essayez d'utiliser0 comme étape, vous obtiendrez une erreur.

Maintenant que vous savez comment utiliserstep, vous pouvez enfin revisiter cette boucle que nous avons vue précédemment avec une division par3.

Essayez par vous-même:

for i in range(3, 16, 3):
    quotient = i / 3
    print(f"{i} divided by 3 is {int(quotient)}.")

Votre sortie ressemblera exactement à la sortie de la boucle for que vous avez vue plus tôt dans cet article, lorsque vous utilisiez la liste nomméenumbers_divisible_by_three:

3 divided by 3 is 1.
6 divided by 3 is 2.
9 divided by 3 is 3.
12 divided by 3 is 4.
15 divided by 3 is 5.

Comme vous le voyez dans cet exemple, vous pouvez utiliser l'argumentstep pour augmenter vers un nombre plus élevé. C'est ce qu'on appelle l'incrémentation.

Incrémentation avecrange()

Si vous voulez incrémenter, vous avez besoin questep soit un nombre positif. Pour avoir une idée de ce que cela signifie dans la pratique, saisissez le code suivant:

for i in range(3, 100, 25):
    print(i)

Si votrestep est25, alors la sortie de votre boucle ressemblera à ceci:

3
28
53
78

Vous avez obtenu une plage de nombres qui étaient chacun supérieurs au nombre précédent de25, lesstep que vous avez fournis.

Maintenant que vous avez vu comment vous pouvez avancer dans une plage, il est temps de voir comment vous pouvez reculer.

Décrémentation avecrange()

Si votrestep est positif, alors vous passez à travers une série de nombres croissants et vous augmentez. Si votrestep est négatif, alors vous passez à travers une série de nombres décroissants et décrémentez. Cela vous permet de parcourir les chiffres à l'envers.

Dans l'exemple suivant, votrestep est-2. Cela signifie que vous allez décrémenter de2 pour chaque boucle:

for i in range(10, -6, -2):
    print(i)

La sortie de votre boucle de décrémentation ressemblera à ceci:

10
8
6
4
2
0
-2
-4

Vous avez obtenu une plage de nombres qui étaient chacun plus petits que le nombre précédent de2, lesabsolute value desstep que vous avez fournis.

La manière la plus pythonique de créer une plage qui décrémente est d'utiliserrange(start, stop, step). Mais Python a une fonctionreversed intégrée. Si vous encapsulezrange() dansreversed(), vous pouvez alors imprimer les entiers dans l'ordre inverse.

Essayez ceci:

for i in reversed(range(5)):
    print(i)

Vous obtiendrez ceci:

4
3
2
1
0

range() permet d'itérer sur une séquence décrémentante de nombres, alors quereversed() est généralement utilisé pour boucler une séquence dans l'ordre inverse.

Note:reversed() fonctionne également avec des chaînes. Vous pouvez en savoir plus sur la fonctionnalité dereversed() avec des chaînes enHow to Reverse a String in Python.

Exemples d’utilisation avancée de la fonctionrange() de Python

Maintenant que vous connaissez les bases de l'utilisation derange(), il est temps de creuser un peu plus.

range() est principalement utilisé à deux fins:

  1. Exécuter le corps d'une boucle for un certain nombre de fois

  2. Créer des itérables d'entiers plus efficaces que ce qui peut être fait aveclists or tuples

La première utilisation est probablement la plus courante, et vous pourriez faire valoir queitertools vous donne un moyen plus efficace de construire des itérables querange().

Voici quelques points supplémentaires à garder à l'esprit lorsque vous utilisez la portée.

range() est un type en Python:

>>>

>>> type(range(3))

Vous pouvez accéder aux éléments d'unrange() par index, comme vous le feriez avec une liste:

>>>

>>> range(3)[1]
1
>>> range(3)[2]
2

Vous pouvez même utiliser la notation de découpage sur unrange(), mais la sortie dans une REPL peut sembler un peu étrange au début:

>>>

>>> range(6)[2:5]
range(2, 5)

Bien que cette sortie puisse sembler étrange, découper unrange() renvoie simplement un autrerange().

Le fait que vous puissiez accéder aux éléments d'unrange() par index et découper unrange() met en évidence un fait important:range() est paresseux, contrairement à une liste, maisisn’t an iterator.

Flottants etrange()

Vous avez peut-être remarqué que tous les nombres que nous avons traités jusqu'à présent étaient des nombres entiers, également appelés entiers. C'est parce querange() ne peut prendre que des entiers comme arguments.

Un mot sur les flotteurs

En Python, si un nombre n'est pas un nombre entier, alors c'est un flottant. Il existe quelques différences entre les entiers et les flottants.

Un entier (type de donnéesint):

  • Est un nombre entier

  • N'inclut pas de point décimal

  • Peut être positif, négatif ou0

Un nombre à virgule flottante (type de donnéesfloat):

  • Peut être n'importe quel nombre qui inclut un point décimal

  • Peut être positif ou négatif

Essayez d'appelerrange() avec un flottant et voyez ce qui se passe:

for i in range(3.3):
    print(i)

Vous devriez obtenir le message d'erreur suivant:

Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'float' object cannot be interpreted as an integer

Si vous devez trouver une solution de contournement qui vous permettra d'utiliser des flottants, vous pouvez utiliser NumPy.

Utilisation derange() avec NumPy

NumPy est une bibliothèque Python tierce. Si vous allez utiliser NumPy, votre première étape consiste à vérifier si vous l'avez installé.

Voici comment procéder dans votre REPL:

>>>

>>> import numpy

Si vous obtenez unModuleNotFoundError, vous devez l'installer. Pour ce faire, accédez à votre ligne de commande et entrezpip install numpy.

Une fois que vous l'avez installé, insérez ce qui suit:

import numpy as np

np.arange(0.3, 1.6, 0.3)

Il retournera ceci:

array([0.3, 0.6, 0.9, 1.2, 1.5])

Si vous souhaitez imprimer chaque numéro sur sa propre ligne, vous pouvez procéder comme suit:

import numpy as np

for i in np.arange(0.3, 1.6, 0.3):
    print(i)

Voici la sortie:

0.3
0.6
0.8999999999999999
1.2
1.5

D'où vient0.8999999999999999?

Les ordinateurs ont du mal à enregistrer les nombres à virgule flottante décimaux en nombres à virgule flottante binaire. Cela conduit à toutes sortes de représentations inattendues de nombres.

Note: Pour en savoir plus sur les raisons pour lesquelles il y a des problèmes de représentation décimale, vous pouvez consulterthis article et lesPython docs.

Vous voudrez peut-être également jeter un coup d'œil auxdecimal library, qui constituent un peu une dégradation en termes de performances et de lisibilité, mais vous permettent de représenter exactement les nombres décimaux.

Une autre option consiste à utiliserround(), sur lequel vous pouvez en savoir plus dansHow to Round Numbers in Python. Gardez à l'esprit queround() a ses propres bizarreries qui pourraient générer des résultats surprenants!

Que ces erreurs en virgule flottante soient ou non un problème pour vous dépend du problème que vous résolvez. Les erreurs vont être quelque chose comme la 16e décimale, ce qui est insignifiant la plupart du temps. Ils sont si petits que, à moins que vous ne travailliez sur le calcul des trajectoires orbitales des satellites ou quelque chose du genre, vous n'avez pas à vous en préoccuper.

Vous pouvez également utilisernp.linspace(). Il fait essentiellement la même chose mais utilise des paramètres différents. Avecnp.linspace(), vous spécifiezstart etend (tous deux inclus) ainsi que la longueur du tableau (au lieu destep).

Par exemple,np.linspace(1, 4, 20) donne 20 nombres également espacés:1.0, ..., 4.0. Par contre,np.linspace(0, 0.5, 51) donne0.00, 0.01, 0.02, 0.03, ..., 0.49, 0.50.

Note: Pour en savoir plus, vous pouvez lireLook Ma, No For-Loops: Array Programming With NumPy et ce pratiqueNumPy reference.

Allez-y et boucle

Vous comprenez maintenant comment utiliserrange() et contourner ses limitations. Vous avez également une idée de l'évolution de cette fonction importante entre Python 2 et Python 3.

La prochaine fois que vous devrez effectuer une action un certain nombre de fois, vous serez prêt à boucler votre cœur!

Pythoning heureux!