Python >> Tutoriel Python >  >> Python

Comment inverser une liste en Python ?

Résumé  :Il n'y a que trois meilleures façons d'inverser l'ordre des éléments de la liste :

  • list.reverse() - Idéal si vous souhaitez inverser les éléments de la liste en place .
  • list[::-1] — Idéal si vous voulez écrire un code concis pour renvoyer une nouvelle liste avec des éléments inversés.
  • reversed(list) — Idéal si vous voulez itérer sur tous les éléments d'une liste dans l'ordre inverse sans changer la liste d'origine.

La méthode list.reverse() peut être 37 % plus rapide que reversed(list) car aucun nouvel objet ne doit être créé.


Lorsque je relis le code de mes élèves, je me rends souvent compte qu'ils connaissent une ou deux façons de résoudre un problème, mais qu'ils ne savent pas quelle est la meilleure pour un problème particulier. Dans cet article, vous apprendrez à inverser une liste et quelle est la manière la plus Pythonic dans un problème donné. Alors, plongeons-y !

Problème :Étant donné une liste d'éléments. Comment inverser l'ordre des éléments dans la liste (plate).

Exemple :Supposons que vous ayez la liste suivante :

['Alice', 'Bob', 'Carl', 'Dora']

Votre but est d'inverser les éléments pour obtenir le résultat suivant :

['Dora', 'Carl', 'Bob', 'Alice']

Il existe plusieurs façons d'inverser une liste. Voici un bref aperçu :

Exercice :Exécutez le code. Dans quel cas utiliseriez-vous la troisième méthode ? A-t-il un avantage par rapport au premier ?

Plongeons plus en détail dans chacune des méthodes !

Méthode 1 :inverser une liste sur place avec list.reverse()

Pour inverser une liste en place et changer l'ordre des éléments dans la liste d'origine, utilisez le list.reverse() méthode. Comme la liste d'origine est modifiée et qu'aucune nouvelle liste n'est renvoyée, cette méthode a des effets secondaires qui peuvent (ou non) être ce dont vous avez besoin.

# Method 1: list.reverse()
names = ['Alice', 'Bob', 'Carl', 'Dora']
names.reverse()
print(names)
# ['Dora', 'Carl', 'Bob', 'Alice']

L'ordre des éléments de la liste d'origine dans la variable names a renversé.

Méthode 2 :Inverser une liste avec découpage [::-1]

Le découpage est un concept pour découper une sous-chaîne à partir d'une chaîne donnée.

Utiliser la notation de découpage s[start:stop:step] pour accéder à tous les step -ième élément à partir de l'index start (inclus) et se terminant par l'index stop (exclu).

Les trois arguments sont facultatifs, vous pouvez donc les ignorer pour utiliser les valeurs par défaut (start=0 , stop=len(lst) , step=1 ). Par exemple, l'expression s[2:4] à partir de la chaîne 'hello' taille la tranche 'll' et l'expression s[:3:2] taille la tranche 'hl' .

Vous pouvez utiliser une taille de pas négative (par exemple, -1) pour trancher de droite à gauche dans l'ordre inverse. Voici comment vous pouvez l'utiliser pour inverser une liste en Python :

# Method 2: Reverse a List with Slicing
names = ['Alice', 'Bob', 'Carl', 'Dora']
names = names[::-1]
print(names)
# ['Dora', 'Carl', 'Bob', 'Alice']

Cette méthode est la plus concise et la plus performante car la tranche a une représentation mémoire efficace. C'est pourquoi les codeurs experts préféreront souvent le tranchage avec une taille de pas négative sur le list.reverse() méthode.

Méthode 3 :Inverser une liste avec Iterator reversed(list)

Le list.reverse() La méthode inverse une liste en place (c'est une méthode - et les méthodes ont tendance à modifier les objets sur lesquels elles sont appelées). Mais que se passe-t-il si vous souhaitez inverser une liste et renvoyer un nouvel objet de liste ? Bien que vous puissiez utiliser le découpage en tranches pour cela, une méthode encore meilleure consiste à utiliser la fonction Python intégrée reversed(list).

Le reversed() La fonction a un gros avantage par rapport au découpage : elle renvoie un objet itérateur plutôt qu'une liste complète. Comparé à une liste, un itérateur a une représentation plus conviviale en mémoire et si vous n'avez pas besoin d'une liste, il est généralement préférable de vivre avec un itérateur (par exemple, pour parcourir tous les éléments dans l'ordre inverse).

# Method 3: reversed()
names = ['Alice', 'Bob', 'Carl', 'Dora']
names = reversed(names)
print(list(names))
# ['Dora', 'Carl', 'Bob', 'Alice']

Cependant, dans cet extrait de code, vous voulez en fait une liste, vous devez donc convertir l'itérateur en liste en utilisant le list(...) constructeur. Dans ce cas, il est préférable d'utiliser le découpage names[::-1] comme indiqué dans la méthode précédente.

Méthode 4 :inverser une liste avec indexation et boucle simple

Les codeurs débutants et les codeurs venant d'autres langages de programmation aiment souvent utiliser des schémas d'indexation pour manipuler des éléments de séquence (ils ne savent pas mieux). Pour plus de compréhensibilité, je voulais inclure la méthode suivante pour inverser une liste en utilisant rien d'autre qu'une simple indexation, une boucle for et le range() fonction.

names = ['Alice', 'Bob', 'Carl', 'Dora']
l = []
for i in range(len(names)-1, -1, -1):
    l.append(names[i])
print(l)
# ['Dora', 'Carl', 'Bob', 'Alice']

Le range(len(names)-1, -1, -1) la fonction retourne un itérateur qui commence par l'index len(names)-1 qui est le dernier index dans la variable names . Il va jusqu'à 0 (inclus) en utilisant une taille de pas négative -1.

Méthode 5 :inverser une liste avec indexation négative

L'extrait de code précédent peut être optimisé (à mon avis) en utilisant une indexation négative. Dans tous les cas, c'est bien si vous savez comment utiliser correctement l'indexation négative en Python, c'est-à-dire accéder aux éléments par la droite plutôt que par la gauche.

Élément Alice Bob Carl Dora
Index 0 1 2 3
Indice négatif -4 -3 -2 -1

Voici comment tirer parti de l'indexation négative pour accéder aux éléments dans l'ordre inverse d'une boucle for de base :

# Method 5: Negative Indexing
names = ['Alice', 'Bob', 'Carl', 'Dora']
l = []
for i in range(1, len(names) + 1):
    l.append(names[-i])
print(l)
# ['Dora', 'Carl', 'Bob', 'Alice']

Notez que la dernière valeur prise par la variable i est i=4 . Utilisé comme index négatif, vous accédez à l'élément names[-4] == Alice dernière.

Évaluation des performances

Comparons la vitesse de ces cinq méthodes !

Dans le code suivant, vous comparez le temps d'exécution de chacune des cinq méthodes pour inverser une liste de cinq éléments et imprimez le temps qu'il faut pour l'exécuter 10 000 fois dans le shell.

Exercice  : Cliquez sur "Exécuter" et voyez quelle méthode gagne dans votre navigateur ! Combien de temps faut-il pour inverser une liste de 100 000 éléments ?

Vous pouvez également copier-coller le code et l'exécuter sur votre ordinateur :

def reverse1():
    names = ['Alice', 'Bob', 'Carl', 'Dora']
    names.reverse()

def reverse2():
    names = ['Alice', 'Bob', 'Carl', 'Dora']
    names = names[::-1]

def reverse3():
    names = ['Alice', 'Bob', 'Carl', 'Dora']
    names = reversed(names)

def reverse4():
    names = ['Alice', 'Bob', 'Carl', 'Dora']
    l = []
    for i in range(len(names)-1, -1, -1):
        l.append(names[i])

def reverse5():
    names = ['Alice', 'Bob', 'Carl', 'Dora']
    l = []
    for i in range(1, len(names) + 1):
        l.append(names[-i])

import timeit
print('M1: ', timeit.timeit(reverse1, number=10000), '--> list.reverse()')
print('M2: ', timeit.timeit(reverse2, number=10000), '--> slicing')
print('M3: ', timeit.timeit(reverse3, number=10000), '--> reversed()')
print('M4: ', timeit.timeit(reverse4, number=10000), '--> loop')
print('M5: ', timeit.timeit(reverse5, number=10000), '--> loop + negative index')

La méthode la plus performante sur mon ordinateur est la list.reverse() méthode :

M1:  0.0012140999999999957 --> list.reverse()
M2:  0.0016616999999999882 --> slicing
M3:  0.0019155999999999618 --> reversed()
M4:  0.005595399999999973 --> loop
M5:  0.006663499999999989 --> loop + negative index

Il est intéressant de voir que les méthodes 4 et 5 les moins lisibles et les moins concises sont aussi les plus lentes ! Notez que nous n'avons pas converti l'itérateur renvoyé par le reversed() méthode à une liste—sinon, cela aurait ajouté quelques millisecondes au résultat.

Bien qu'il ne s'agisse pas d'une évaluation scientifique des performances, cela indique que "se tenir sur les épaules de géants" en réutilisant du code existant est généralement une bonne idée !

Conclusion

Il n'y a que trois meilleures façons d'inverser l'ordre des éléments de la liste :

  • list.reverse() — Idéal si vous souhaitez inverser les éléments de la liste en place.
  • list[::-1] — Idéal si vous souhaitez écrire un code concis pour renvoyer une nouvelle liste avec des éléments inversés.
  • reversed(list) — Idéal si vous souhaitez itérer sur tous les éléments d'une liste dans l'ordre inverse sans modifier la liste d'origine.

Vous avez vu dans l'évaluation que la méthode list.reverse() peut être 37 % plus rapide que reversed(list) car aucun nouvel objet ne doit être créé.


Post précédent