Inverser n'importe quel objet avec Python

Découvrez quelques techniques et astuces pour facilement inverser plusieurs types d'objets (chaînes de caractères, listes, nombres) avec Python.

Publié le par Thibault Houdon (mis à jour le )
paceTemps de lecture estimé : 15 minutes

Savoir inverser l'ordre des éléments dans une variable ou dans un objet est un basique de la programmation. C'est une opération utile qui me sert régulièrement dans mon apprentissage du métier de développeur !

Avec Python, comme dans d'autres langages, il existe plusieurs façons d'y arriver (bien sûr, pourquoi faire simple quand on peut faire compliqué).

Ce que je te propose, c'est qu'on mette tout ça au clair une bonne fois pour toutes.

Utiliser le slicing

e te le dis d'entrée de jeu, c'est la meilleure manière de procéder et aussi celle que j'utilise à chaque fois que j'ai besoin de faire ça.

En plus, ça va vite. Mais ça, je t'en parle un peu plus loin.

Comme tu le sais sûrement, avec Python, on a la possibilité d'accéder aux informations d'un objet en utilisant le slicing (ou le "découpage en tranche" en français).

Je te montre.

word = 'docstring'
print(word[1:-1])
# ocstrin

J'utilise les crochets pour spécifier un intervalle et j'insère ensuite des valeurs séparées par deux-points pour dire que je souhaite exclure le premier et le dernier élément de ma chaîne de caractères.

Si c'est encore un peu flou pour toi, tu peux trouver d'autres exemples dans ce glossaire.

Sache que tu peux également demander à Python d'ignorer certains éléments en précisant un pas.

Ça se fait en ajoutant à nouveau deux-points, puis la valeur du pas :

word = 'docstring'
print(word[1:-1:2])
# osrn

Remarque comme Python a subtilement ignoré une lettre sur deux.

Là, le résultat n'est pas très parlant, je te l'accorde ! Mais retiens bien ce principe car c'est justement l'utilisation de ce pas qui va te permettre d'inverser un objet très facilement.

word = 'docstring'
print(word[::-1])
# gnirtscod

Concentre-toi sur le [::-1].

Comme je ne donne ni de valeur de valeur de début ni de valeur de fin, Python comprend qu'il doit prendre en compte toute la chaîne de caractères.

👉 Par contre, le fait de préciser un pas de -1 indique à Python qu'il doit commencer à récupérer l'objet depuis la fin !

Plutôt sympa non ?

Avec une boucle for classique

En tant que débutant, c'est probablement ce qui te viendrait à l'esprit naturellement. Ça pourrait ressembler à quelque chose comme ça :

word = 'docstring'
reversed_word = ''
for letter in word:
    reversed_word = letter + reversed_word
print(reversed_word)
# gnirtscod

Ici, pas de mystère ! On passe sur chaque élément de la chaîne de caractères et on vient concaténer cet élément avec ce qu'on a déjà inversé.

On comprend vite et ça fait le boulot. Mais autant de lignes de code pour ça, c'est pas terrible en termes de lisibilité.

De plus, il faut que tu saches qu'à chaque passage dans la boucle, on va créer un nouvel objet en mémoire car ici on travaille avec une chaîne de caractères (str), qui est un objet immuable !

Je te déconseille donc fortement d'utiliser cette méthode bien qu'elle soit assez répandue.

Derrière Python, il y a des personnes pragmatiques. Elles ont développé pour nous des méthodes prêtes à l'emploi pour pas mal de trucs.

Inverser quelque chose en fait partie.

reverse et reversed

La méthode reverse ne retourne rien.

Enfin si, elle te retourne None (donc rien). Elle se contente simplement d'inverser l'ordre des éléments de ta collection. Pas besoin donc de réassigner ce résultat dans une variable.

Ne faites donc pas cette erreur :

liste = ['Python', 'Javascript', 'PHP', 'Ruby']
liste = liste.reverse()
print(liste)
# None

Dans le titre, je t'ai dis que tu pourrais inverser n'importe quel objet. Je t'ai un peu menti. Avec la méthode reverse, tu peux simplement agir sur les objets muables comme les listes !Passons à la dernière.

reversed, c'est une fonction et pas une méthode. De ce fait, elle n'agit pas directement sur ton objet. Elle va obligatoirement te renvoyer une valeur en retour de l'appel.

Comme ça :

word = 'docstring'
reversed_word = reversed(word)
print(reversed_word)
# reversed object at 0x105bf3400

Le truc bizarre qui est retourné, c'est un reverse iterator object.

Cet objet est un itérable qui représente ton objet inversé.

Cependant, tu ne peux pas l'afficher en tant que tel. Par contre, comme c'est un objet itérable, tu peux boucler dessus et faire ce que tu veux 👍

word = 'docstring'
for letter in reversed(word):
    print(letter)
# g
# n
# i
# ...

Et si jamais tu souhaites quand même afficher cet objet sous forme de liste, tu peux le convertir en liste comme ceci :

reversed_word_as_list = list(reversed(word))
print(reversed_word_as_list)
# ['d', 'o', 'c', 's', 't', 'r', 'i', 'n', 'g']

Comme je te le disais plus haut, utiliser le slicing est de loin la méthode la plus efficace pour ce type d'opération.

Pour dix millions d'inversions, on est à moins d'une seconde avec le slicing (beaucoup moins en fait).

La méthode reverse et la fonction reversed s'en sortent pas trop mal avec un temps d'exécution autour des sept secondes.

Par contre, avec la boucle for, tu t'en doutes, on dépasse largement les 30 secondes.

Pour résumer

On l'a vu, Python nous donne tous les outils nécessaires pour inverser n'importe quel type d'objet efficacement.

Évidemment, si tu n'es pas débutant, toutes ces notions tu les maîtrises déjà. Toutefois, j'espère quand même que tu auras appris quelque chose en lisant ces lignes.

Bref, la prochaine fois que tu auras à écrire un détecteur de palindrome lors d'un test technique (ça m'est déjà arrivé, je t'assure), souviens-toi que ça peut être fait en une ligne :

mot = "kayak"
print("C'est un palindrome !") if mot == mot[::-1] else print("Nope, pas un palindrome")