ne pouvez-vous pas simplement utiliser: array [:: - 1]?
kdlannoy
134
@kdlannoy Selon la page liée à la réponse, "Par rapport au découpage étendu, tel que la plage (1,4) [:: - 1], inversé () est plus facile à lire, s'exécute plus rapidement et utilise beaucoup moins de mémoire. "
Jim Oldfield
5
Lorsque j'ai testé ce découpage était environ deux fois plus rapide (lors de l'inversion d'une liste d'éléments 10k et de sa création). Je n'ai cependant pas testé la consommation de mémoire. reversepeut être plus rapide cependant, si vous n'avez pas besoin de caster la liste par la suite.
Dakkaron
5
il convient de noter que ce n'est pas la même chose que l'inverse ([1,2,3]), nb le «d» à la fin ... qui est l'une des autres réponses ci-dessous, qui fait cela en place, alors que cela renvoie un itérateur.
Luciano
14
Pourquoi utiliser reversed()au lieu de trancher? Lisez le Zen of Python, règle numéro 7: la lisibilité compte!
Cela fonctionne pour n'importe quel interable, pas seulement pour les listes. L'inconvénient est qu'il n'est pas en place.
Swiss
6
@Tim, il renvoie une tranche, donc ne change pas le contenu de la liste réelle
fortran
12
@lunixbochs inversé renvoie un itérateur et non une liste en Python 3.
Swiss
2
à moins d'être naturellement correctement encapsulé dans le réseau
Einar Petersen
2
Je suis d'accord avec @Swiss. +1 puisque la question était, je dois avoir les éléments d'un tableau mais de la fin au début. - reversedrenvoie un listreverseiteratorobjet (Python 2.7.x), qui doit ensuite être itéré via - le découpage inversé retourne une liste / tuple / str inversée (selon ce que vous découpez). @Einar Petersen qui inverse une chaîne, donc la sortie est correcte. Essayez:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
Aaron Newton
368
>>> L =[0,10,20,40]>>> L.reverse()>>> L
[40,20,10,0]
Utiliser le découpage, par exemple array = array [:: - 1], est une astuce intéressante et très Pythonic, mais peut-être un peu obscure pour les débutants. L'utilisation de la méthode reverse () est un bon moyen de procéder au codage au jour le jour car elle est facilement lisible.
Cependant, si vous devez inverser une liste en place comme dans une question d'entrevue, vous ne pourrez probablement pas utiliser des méthodes intégrées comme celles-ci. L'intervieweur examinera comment vous abordez le problème plutôt que la profondeur des connaissances en Python, une approche algorithmique est requise. L'exemple suivant, en utilisant un échange classique, pourrait être une façon de le faire: -
def reverse_in_place(lst):# Declare a function
size = len(lst)# Get the length of the sequence
hiindex = size -1
its = size/2# Number of iterations requiredfor i in xrange(0, its):# i is the low index pointer
temp = lst[hiindex]# Perform a classic swap
lst[hiindex]= lst[i]
lst[i]= temp
hiindex -=1# Decrement the high index pointerprint"Done!"# Now test it!!
array =[2,5,8,9,12,19,25,27,32,60,65,1,7,24,124,654]print array # Print the original sequence
reverse_in_place(array)# Call the function passing the listprint array # Print reversed list**The result:**[2,5,8,9,12,19,25,27,32,60,65,1,7,24,124,654]Done![654,124,24,7,1,65,60,32,27,25,19,12,9,8,5,2]
Notez que cela ne fonctionnera pas sur les tuples ou les séquences de chaînes, car les chaînes et les tuples sont immuables, c'est-à-dire que vous ne pouvez pas y écrire pour changer les éléments.
Le swap classique pourrait se faire via lst[hiindex], lst[i] = lst[i], lst[hiindex], je pense ... ;-)
Samoth
@Samoth Cette syntaxe n'est pas aussi claire et le comportement n'est pas exactement évident. Des étapes distinctes ont plus de sens.
Anthony
pourquoi les gens disent que des choses comme array [:: - 1] sont pythoniques? Le python zen nous apprend qu'explicite vaut mieux que l'implicite et la lisibilité. Des trucs comme ça ne sont pas explicites et lisibles du tout.
k4ppa
1
@ k4ppa: array[::-1]est parfaitement lisible et parfaitement explicite si vous connaissez Python . "Lisible" ne signifie pas "quelqu'un qui n'a jamais utilisé le découpage Python auparavant doit être capable de le lire"; la [::-1]tranche d'inversion est un idiome ridiculement commun en Python (vous le rencontrerez tout le temps dans le code existant), et il est parfaitement lisible si vous utilisez régulièrement Python . Bien sûr, first10 = [], for i in range(10): first10.append(array[i])est claire et explicite, mais cela ne fait pas mieux que first10 = array[:10].
ShadowRanger
19
Je trouve (contrairement à d'autres suggestions) que l.reverse()c'est de loin le moyen le plus rapide pour inverser une longue liste en Python 3 et 2. Je serais intéressé de savoir si d'autres peuvent reproduire ces timings.
l[::-1]est probablement plus lent car il copie la liste avant de l'inverser. L'ajout de l' list()appel autour de l'itérateur effectué par reversed(l)doit ajouter une surcharge. Bien sûr, si vous voulez une copie de la liste ou un itérateur, utilisez ces méthodes respectives, mais si vous voulez simplement inverser la liste, cela l.reverse()semble être le moyen le plus rapide.
Les fonctions
def rev_list1(l):return l[::-1]def rev_list2(l):return list(reversed(l))def rev_list3(l):
l.reverse()return l
list.reverseest le plus rapide, car il s'inverse sur place
warvariuc
Vous avez raison list.reverse()est le plus rapide, mais vous êtes pénalisant reversed(ce qui est mieux utilisé lorsque vous ne voulez pas de nouveau list, juste pour itérer un existant listdans l'ordre inverse sans muter l'original), et la tranche (qui évite également de muter l'original list, et est généralement plus rapide que reversedlorsque l'entrée est petite). Oui, si vous n'avez pas besoin de la copie, tout ce qui copie est plus cher, mais la plupart du temps, vous ne voulez pas modifier la valeur d'origine.
ShadowRanger
On dirait que ça reversedperd tout delist.reverse() même, mais étant donné qu'il ne mute pas l'entrée list, c'est mieux dans de nombreux cas. La perte pour reversedest faible (~ 1/6 de plus que list.reverse()).
Je cherchais comment faire cela sans utiliser la fonction inverse. Merci.
Bernard 'Beta Berlin' Parah
Ou pour inverser sur place, utilisez list = list.reverse ()
SimonM
6
Résumé des méthodes avec explication et résultats de synchronisation
Il existe plusieurs bonnes réponses, mais dispersées et la plupart n'indiquent pas les différences fondamentales de chaque approche.
Dans l'ensemble, il est préférable d'utiliser des fonctions / méthodes intégrées pour inverser, comme avec à peu près n'importe quelle fonction. Dans ce cas, ils sont environ 2 à 8 fois plus rapides sur les listes courtes (10 éléments), et jusqu'à ~ 300 + fois plus rapides sur les listes longues par rapport à un moyen d'indexation créé manuellement. Cela a du sens car ils ont des experts qui les créent, les examinent et les optimisent. Ils sont également moins sujets aux défauts et plus susceptibles de gérer les cas des bords et des coins.
Demandez-vous également si vous souhaitez:
Inverser une liste existante sur place
La meilleure solution est la object.reverse()méthode
Créez un itérateur de l'inverse de la liste (car vous allez l'alimenter sur une boucle for, un générateur, etc.)
La meilleure solution est de reversed(object)créer l'itérateur
ou créez une copie complète dans l'ordre inverse
La meilleure solution consiste à utiliser des tranches avec une taille de pas de -1: object[::-1]
Script de test
Voici le début de mon script de test pour les méthodes couvertes. Rassemblez tous les extraits de code dans cette réponse pour créer un script qui exécutera toutes les différentes façons d'inverser une liste et de chronométrer chacune (sortie affichée dans la dernière section).
from timeit import timeit
from copy import copy
def time_str_ms(t):return'{0:8.2f} ms'.format(t *1000)
Méthode 1: inverser en place avec obj.reverse ()
Si l'objectif est simplement d'inverser l'ordre des éléments dans une liste existante, sans les parcourir en boucle ni obtenir une copie avec laquelle travailler, utilisez la <list>.reverse()fonction. Exécutez ceci directement sur un objet de liste, et l'ordre de tous les éléments sera inversé:
Notez que ce qui suit va inverser la variable d'origine qui est donnée, même si elle retourne également la liste inversée. c'est-à-dire que vous pouvez créer une copie en utilisant cette sortie de fonction. En règle générale, vous ne feriez pas de fonction pour cela, mais je l'ai fait pour utiliser le code de synchronisation à la fin.
Nous allons tester les performances de ces deux façons - tout d'abord inverser une liste sur place (modifie la liste d'origine), puis copier la liste et l'inverser ensuite.
def rev_in_place(mylist):
mylist.reverse()return mylist
def rev_copy_reverse(mylist):
a = copy(mylist)
a.reverse()return a
Méthode 2: inverser une liste à l'aide de tranches obj[::-1]
La méthode de découpage d'index intégrée vous permet de faire une copie d'une partie de n'importe quel objet indexé.
Cela n'affecte pas l'objet d'origine
Il construit une liste complète, pas un itérateur
La syntaxe générique est: <object>[first_index:last_index:step]. Pour exploiter slicing pour créer une liste simple inversée, utilisez: <list>[::-1]. Lorsque vous laissez une option vide, elle les définit sur les valeurs par défaut du premier et du dernier élément de l'objet (inversé si la taille du pas est négative).
L'indexation permet d'utiliser des nombres négatifs, qui comptent de la fin de l'index de l'objet vers l'arrière (c'est-à-dire que -2 est l'avant-dernier élément). Lorsque la taille de l'étape est négative, elle commencera avec le dernier élément et indexera en arrière de ce montant. Il y a une logique de début et de fin associée à cela qui a été optimisée.
def rev_slice(mylist):
a = mylist[::-1]return a
Méthode 3: inverser une liste avec la reversed(obj)fonction itérateur
Il y a une reversed(indexed_object)fonction:
Cela crée un itérateur d'index inverse, pas une liste. Idéal si vous l'alimentez en boucle pour de meilleures performances sur de grandes listes
Cela crée une copie et n'affecte pas l'objet d'origine
Testez avec un itérateur brut et créez une liste à partir de l'itérateur.
def reversed_iterator(mylist):
a = reversed(mylist)return a
def reversed_with_list(mylist):
a = list(reversed(mylist))return a
Méthode 4: Liste inversée avec indexation personnalisée / manuelle
Comme le montre le timing, créer vos propres méthodes d'indexation est une mauvaise idée. Utilisez les méthodes intégrées, sauf si vous devez faire quelque chose de vraiment personnalisé.
Cela dit, il n'y a pas de pénalité énorme avec des listes plus petites, mais lorsque vous augmentez l'échelle, la pénalité devient énorme. Je suis sûr que mon code ci-dessous pourrait être optimisé, mais je m'en tiendrai aux méthodes intégrées.
def rev_manual_pos_gen(mylist):
max_index = len(mylist)-1return[ mylist[max_index - index]for index in range(len(mylist))]def rev_manual_neg_gen(mylist):## index is 0 to 9, but we need -1 to -10return[ mylist[-index-1]for index in range(len(mylist))]def rev_manual_index_loop(mylist):
a =[]
reverse_index = len(mylist)-1for index in range(len(mylist)):
a.append(mylist[reverse_index - index])return a
def rev_manual_loop(mylist):
a =[]
reverse_index = len(mylist)for index, _ in enumerate(mylist):
reverse_index -=1
a.append(mylist[reverse_index])return a
Planification de chaque méthode
Voici le reste du script pour chronométrer chaque méthode d'inversion. Il montre que l'inversion en place obj.reverse()et la création de l' reversed(obj)itérateur sont toujours les plus rapides, tandis que l'utilisation de tranches est le moyen le plus rapide de créer une copie.
Cela prouve également de ne pas essayer de créer une façon de le faire par vous-même, sauf si vous le devez!
loops_to_test =100000
number_of_items =10
list_to_reverse = list(range(number_of_items))if number_of_items <15:print("a: {}".format(list_to_reverse))print('Loops: {:,}'.format(loops_to_test))# List of the functions we want to test with the timer, in print order
fcns =[rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__)for fcn in fcns ])for fcn in fcns:
a = copy(list_to_reverse)# copy to start fresh each loop
out_str =' | out = {}'.format(fcn(a))if number_of_items <15else''# Time in ms for the given # of loops on this fcn
time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))# Get the output string for this function
fcn_str ='{}(a):'.format(fcn.__name__)# Add the correct string length to accommodate the maximum fcn name
format_str ='{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string +4)print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))
Résultats de chronométrage
Les résultats montrent que la mise à l'échelle fonctionne mieux avec les méthodes intégrées les mieux adaptées à une tâche donnée. En d'autres termes, à mesure que le nombre d'éléments d'objet augmente, les méthodes intégrées commencent à avoir des résultats de performances bien supérieurs.
Il vaut également mieux utiliser la meilleure méthode intégrée qui réalise directement ce dont vous avez besoin que de lier les choses ensemble. c'est-à-dire que le découpage en tranches est préférable si vous avez besoin d'une copie de la liste inversée - c'est plus rapide que de créer une liste à partir de la reversed()fonction, et plus rapide que de faire une copie de la liste et de faire ensuite sur place obj.reverse(). Mais si l'une de ces méthodes est vraiment tout ce dont vous avez besoin, elles sont plus rapides, mais jamais plus du double de la vitesse. Pendant ce temps, les méthodes manuelles personnalisées peuvent prendre des ordres de grandeur plus longtemps, en particulier avec de très grandes listes.
Pour la mise à l'échelle, avec une liste de 1000 éléments, l' reversed(<list>)appel de fonction prend ~ 30 ms pour configurer l'itérateur, l'inversion en place ne prend que ~ 55 ms, l'utilisation de la méthode slice prend ~ 210 ms pour créer une copie de la liste inversée complète, mais la méthode manuelle la plus rapide que j'ai faite a pris ~ 8400 ms !!
Avec 2 articles dans la liste:
a:[0,1]Loops:100,000
rev_in_place(a):24.70 ms | out =[1,0]
reversed_iterator(a):30.48 ms | out =<list_reverseiterator object at 0x0000020242580408>
rev_slice(a):31.65 ms | out =[1,0]
rev_copy_reverse(a):63.42 ms | out =[1,0]
reversed_with_list(a):48.65 ms | out =[1,0]
rev_manual_pos_gen(a):98.94 ms | out =[1,0]
rev_manual_neg_gen(a):88.11 ms | out =[1,0]
rev_manual_index_loop(a):87.23 ms | out =[1,0]
rev_manual_loop(a):79.24 ms | out =[1,0]
Avec 10 articles dans la liste:
rev_in_place(a):23.39 ms | out =[9,8,7,6,5,4,3,2,1,0]
reversed_iterator(a):30.23 ms | out =<list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a):36.01 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_copy_reverse(a):64.67 ms | out =[9,8,7,6,5,4,3,2,1,0]
reversed_with_list(a):50.77 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_pos_gen(a):162.83 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_neg_gen(a):167.43 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_index_loop(a):152.04 ms | out =[9,8,7,6,5,4,3,2,1,0]
rev_manual_loop(a):183.01 ms | out =[9,8,7,6,5,4,3,2,1,0]
Et avec 1000 articles dans la liste:
rev_in_place(a):56.37 ms
reversed_iterator(a):30.47 ms
rev_slice(a):211.42 ms
rev_copy_reverse(a):295.74 ms
reversed_with_list(a):418.45 ms
rev_manual_pos_gen(a):8410.01 ms
rev_manual_neg_gen(a):11054.84 ms
rev_manual_index_loop(a):10543.11 ms
rev_manual_loop(a):15472.66 ms
Si vous souhaitez stocker les éléments de la liste inversée dans une autre variable, vous pouvez utiliser revArray = array[::-1]ou revArray = list(reversed(array)).
Mais la première variante est légèrement plus rapide:
z = range(1000000)
startTimeTic = time.time()
y = z[::-1]print("Time: %s s"%(time.time()- startTimeTic))
f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))print("Time: %s s"%(time.time()- startTimeTic))
Utiliser une certaine logique de la vieille école pour pratiquer des entretiens.
Permutation des numéros d'avant en arrière. Utilisation de deux pointeursindex[0] and index[last]
def reverse(array):
n = array
first =0
last = len(array)-1while first < last:
holder = n[first]
n[first]= n[last]
n[last]= holder
first +=1
last -=1return n
input ->[-1,1,2,3,4,5,6]
output ->[6,1,2,3,4,5,-1]
Si nous divisons la liste en deux et échangeons le premier avec le dernier index, la complexité temporelle sera plus efficace que l'échantillon répertorié.
Israel Manzo
3
Vous pouvez également utiliser le complément au niveau du bit de l'index du tableau pour parcourir le tableau à l'envers:
>>> array =[0,10,20,40]>>>[array[~i]for i, _ in enumerate(array)][40,20,10,0]
Quoi que vous fassiez, ne le faites pas de cette façon.
À strictement parler, la question n'est pas de savoir comment retourner une liste en sens inverse, mais plutôt comment inverser une liste avec un exemple de nom de liste array.
Pour inverser une liste nommée, "array"utilisez array.reverse().
La méthode de découpage incroyablement utile telle que décrite peut également être utilisée pour inverser une liste en place en définissant la liste comme une modification découpée d'elle-même en utilisant array = array[::-1].
Avec un minimum de fonctions intégrées, en supposant que ce sont les paramètres de l'entretien
array =[1,2,3,4,5,6,7,8]
inverse =[]#create container for inverse array
length = len(array)#to iterate later, returns 8
counter = length -1#because the 8th element is on position 7 (as python starts from 0)for i in range(length):
inverse.append(array[counter])
counter -=1print(inverse)
Mieux avec l' //opérateur de division de plancher.
Valentin Podkamennyi
1
Vous pouvez toujours traiter la liste comme une pile en faisant simplement ressortir les éléments du haut de la pile à l'arrière de la liste. De cette façon, vous profitez des caractéristiques du premier entré, dernier sorti d'une pile. Bien sûr, vous consommez le 1er tableau. J'aime cette méthode dans la mesure où elle est assez intuitive dans la mesure où vous voyez une liste consommée par le back-end tandis que l'autre est construite par le front-end.
>>> l =[1,2,3,4,5,6]; nl=[]>>>while l:
nl.append(l.pop())>>>print nl
[6,5,4,3,2,1]
Voici un moyen d'évaluer paresseusement l'inverse à l'aide d'un générateur :
def reverse(seq):for x in range(len(seq),-1,-1):#Iterate through a sequence starting from -1 and increasing by -1.yield seq[x]#Yield a value to the generator
Il existe 3 méthodes pour obtenir la liste inversée:
Méthode de découpage 1: reversed_array = array[-1::-1]
Méthode de découpage 2:
reversed_array2 = array[::-1]
Utilisation de la fonction intégrée: reversed_array = array.reverse()
La troisième fonction a en fait inversé l'objet de liste en place. Cela signifie qu'aucune copie des données intactes n'est conservée. C'est une bonne approche si vous ne souhaitez pas conserver l'ancienne version. Mais cela ne semble pas être une solution si vous voulez la version vierge et inversée.
Cette solution est environ 4,5 k fois plus lente que l[::-1], et en même temps beaucoup moins lisible. La programmation fonctionnelle en Python est malheureusement assez lente.
reverse
peut être plus rapide cependant, si vous n'avez pas besoin de caster la liste par la suite.reversed()
au lieu de trancher? Lisez le Zen of Python, règle numéro 7: la lisibilité compte!La syntaxe de tranche étendue est bien expliquée dans l' entrée Quoi de neuf Python pour publication
2.3.5
Sur demande spéciale dans un commentaire, il s'agit de la documentation de tranche la plus récente .
la source
reversed
renvoie unlistreverseiterator
objet (Python 2.7.x), qui doit ensuite être itéré via - le découpage inversé retourne une liste / tuple / str inversée (selon ce que vous découpez). @Einar Petersen qui inverse une chaîne, donc la sortie est correcte. Essayez:co2=['ae','ad','ac','ab','aa','z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'] >>> co2[::-1]
Ou
la source
L=L[::-1]
d'inverser réellement la liste, sinon vous ne retournez que les valeurs en sens inverseb = l[-n:] b.reverse() l = b + l[:len(l) - n]
Il s'agit de dupliquer la liste:
C'est pour inverser la liste en place:
la source
Je pense que la meilleure façon d'inverser une liste en Python est de faire:
Le travail est terminé et vous avez maintenant une liste inversée.
la source
Pour inverser la même liste, utilisez:
Pour affecter une liste inversée à une autre liste, utilisez:
la source
Utiliser le découpage, par exemple array = array [:: - 1], est une astuce intéressante et très Pythonic, mais peut-être un peu obscure pour les débutants. L'utilisation de la méthode reverse () est un bon moyen de procéder au codage au jour le jour car elle est facilement lisible.
Cependant, si vous devez inverser une liste en place comme dans une question d'entrevue, vous ne pourrez probablement pas utiliser des méthodes intégrées comme celles-ci. L'intervieweur examinera comment vous abordez le problème plutôt que la profondeur des connaissances en Python, une approche algorithmique est requise. L'exemple suivant, en utilisant un échange classique, pourrait être une façon de le faire: -
Notez que cela ne fonctionnera pas sur les tuples ou les séquences de chaînes, car les chaînes et les tuples sont immuables, c'est-à-dire que vous ne pouvez pas y écrire pour changer les éléments.
la source
lst[hiindex], lst[i] = lst[i], lst[hiindex]
, je pense ... ;-)array[::-1]
est parfaitement lisible et parfaitement explicite si vous connaissez Python . "Lisible" ne signifie pas "quelqu'un qui n'a jamais utilisé le découpage Python auparavant doit être capable de le lire"; la[::-1]
tranche d'inversion est un idiome ridiculement commun en Python (vous le rencontrerez tout le temps dans le code existant), et il est parfaitement lisible si vous utilisez régulièrement Python . Bien sûr,first10 = []
,for i in range(10): first10.append(array[i])
est claire et explicite, mais cela ne fait pas mieux quefirst10 = array[:10]
.Je trouve (contrairement à d'autres suggestions) que
l.reverse()
c'est de loin le moyen le plus rapide pour inverser une longue liste en Python 3 et 2. Je serais intéressé de savoir si d'autres peuvent reproduire ces timings.l[::-1]
est probablement plus lent car il copie la liste avant de l'inverser. L'ajout de l'list()
appel autour de l'itérateur effectué parreversed(l)
doit ajouter une surcharge. Bien sûr, si vous voulez une copie de la liste ou un itérateur, utilisez ces méthodes respectives, mais si vous voulez simplement inverser la liste, celal.reverse()
semble être le moyen le plus rapide.Les fonctions
liste
Timings Python 3.5
Timings Python 2.7
la source
list.reverse
est le plus rapide, car il s'inverse sur placelist.reverse()
est le plus rapide, mais vous êtes pénalisantreversed
(ce qui est mieux utilisé lorsque vous ne voulez pas de nouveaulist
, juste pour itérer un existantlist
dans l'ordre inverse sans muter l'original), et la tranche (qui évite également de muter l'originallist
, et est généralement plus rapide quereversed
lorsque l'entrée est petite). Oui, si vous n'avez pas besoin de la copie, tout ce qui copie est plus cher, mais la plupart du temps, vous ne voulez pas modifier la valeur d'origine.reversed
perd tout delist.reverse()
même, mais étant donné qu'il ne mute pas l'entréelist
, c'est mieux dans de nombreux cas. La perte pourreversed
est faible (~ 1/6 de plus quelist.reverse()
).la source
Avec
reversed
etlist
:la source
la source
L'utilisation inversée (tableau) serait probablement la meilleure voie.
Si vous avez besoin de comprendre comment cela pourrait être mis en œuvre sans utiliser le intégré
reversed
.Cela devrait prendre du temps O (N).
la source
Résumé des méthodes avec explication et résultats de synchronisation
Il existe plusieurs bonnes réponses, mais dispersées et la plupart n'indiquent pas les différences fondamentales de chaque approche.
Dans l'ensemble, il est préférable d'utiliser des fonctions / méthodes intégrées pour inverser, comme avec à peu près n'importe quelle fonction. Dans ce cas, ils sont environ 2 à 8 fois plus rapides sur les listes courtes (10 éléments), et jusqu'à ~ 300 + fois plus rapides sur les listes longues par rapport à un moyen d'indexation créé manuellement. Cela a du sens car ils ont des experts qui les créent, les examinent et les optimisent. Ils sont également moins sujets aux défauts et plus susceptibles de gérer les cas des bords et des coins.
Demandez-vous également si vous souhaitez:
object.reverse()
méthodereversed(object)
créer l'itérateurobject[::-1]
Script de test
Voici le début de mon script de test pour les méthodes couvertes. Rassemblez tous les extraits de code dans cette réponse pour créer un script qui exécutera toutes les différentes façons d'inverser une liste et de chronométrer chacune (sortie affichée dans la dernière section).
Méthode 1: inverser en place avec obj.reverse ()
Si l'objectif est simplement d'inverser l'ordre des éléments dans une liste existante, sans les parcourir en boucle ni obtenir une copie avec laquelle travailler, utilisez la
<list>.reverse()
fonction. Exécutez ceci directement sur un objet de liste, et l'ordre de tous les éléments sera inversé:Notez que ce qui suit va inverser la variable d'origine qui est donnée, même si elle retourne également la liste inversée. c'est-à-dire que vous pouvez créer une copie en utilisant cette sortie de fonction. En règle générale, vous ne feriez pas de fonction pour cela, mais je l'ai fait pour utiliser le code de synchronisation à la fin.
Nous allons tester les performances de ces deux façons - tout d'abord inverser une liste sur place (modifie la liste d'origine), puis copier la liste et l'inverser ensuite.
Méthode 2: inverser une liste à l'aide de tranches
obj[::-1]
La méthode de découpage d'index intégrée vous permet de faire une copie d'une partie de n'importe quel objet indexé.
La syntaxe générique est:
<object>[first_index:last_index:step]
. Pour exploiter slicing pour créer une liste simple inversée, utilisez:<list>[::-1]
. Lorsque vous laissez une option vide, elle les définit sur les valeurs par défaut du premier et du dernier élément de l'objet (inversé si la taille du pas est négative).L'indexation permet d'utiliser des nombres négatifs, qui comptent de la fin de l'index de l'objet vers l'arrière (c'est-à-dire que -2 est l'avant-dernier élément). Lorsque la taille de l'étape est négative, elle commencera avec le dernier élément et indexera en arrière de ce montant. Il y a une logique de début et de fin associée à cela qui a été optimisée.
Méthode 3: inverser une liste avec la
reversed(obj)
fonction itérateurIl y a une
reversed(indexed_object)
fonction:Testez avec un itérateur brut et créez une liste à partir de l'itérateur.
Méthode 4: Liste inversée avec indexation personnalisée / manuelle
Comme le montre le timing, créer vos propres méthodes d'indexation est une mauvaise idée. Utilisez les méthodes intégrées, sauf si vous devez faire quelque chose de vraiment personnalisé.
Cela dit, il n'y a pas de pénalité énorme avec des listes plus petites, mais lorsque vous augmentez l'échelle, la pénalité devient énorme. Je suis sûr que mon code ci-dessous pourrait être optimisé, mais je m'en tiendrai aux méthodes intégrées.
Planification de chaque méthode
Voici le reste du script pour chronométrer chaque méthode d'inversion. Il montre que l'inversion en place
obj.reverse()
et la création de l'reversed(obj)
itérateur sont toujours les plus rapides, tandis que l'utilisation de tranches est le moyen le plus rapide de créer une copie.Cela prouve également de ne pas essayer de créer une façon de le faire par vous-même, sauf si vous le devez!
Résultats de chronométrage
Les résultats montrent que la mise à l'échelle fonctionne mieux avec les méthodes intégrées les mieux adaptées à une tâche donnée. En d'autres termes, à mesure que le nombre d'éléments d'objet augmente, les méthodes intégrées commencent à avoir des résultats de performances bien supérieurs.
Il vaut également mieux utiliser la meilleure méthode intégrée qui réalise directement ce dont vous avez besoin que de lier les choses ensemble. c'est-à-dire que le découpage en tranches est préférable si vous avez besoin d'une copie de la liste inversée - c'est plus rapide que de créer une liste à partir de la
reversed()
fonction, et plus rapide que de faire une copie de la liste et de faire ensuite sur placeobj.reverse()
. Mais si l'une de ces méthodes est vraiment tout ce dont vous avez besoin, elles sont plus rapides, mais jamais plus du double de la vitesse. Pendant ce temps, les méthodes manuelles personnalisées peuvent prendre des ordres de grandeur plus longtemps, en particulier avec de très grandes listes.Pour la mise à l'échelle, avec une liste de 1000 éléments, l'
reversed(<list>)
appel de fonction prend ~ 30 ms pour configurer l'itérateur, l'inversion en place ne prend que ~ 55 ms, l'utilisation de la méthode slice prend ~ 210 ms pour créer une copie de la liste inversée complète, mais la méthode manuelle la plus rapide que j'ai faite a pris ~ 8400 ms !!Avec 2 articles dans la liste:
Avec 10 articles dans la liste:
Et avec 1000 articles dans la liste:
la source
Si vous souhaitez stocker les éléments de la liste inversée dans une autre variable, vous pouvez utiliser
revArray = array[::-1]
ourevArray = list(reversed(array))
.Mais la première variante est légèrement plus rapide:
Production:
la source
timeit
.ORGANISATION DES VALEURS:
En Python, l'ordre des listes peut également être manipulé avec le tri , organisant vos variables dans l'ordre numérique / alphabétique:
Temporairement:
Permanent:
Vous pouvez trier avec le drapeau "reverse = True" :
SANS ORGANISER
Vous ne souhaitez peut-être pas trier les valeurs, mais uniquement inverser les valeurs. Ensuite, nous pouvons le faire comme ceci:
** Les nombres ont priorité sur l'alphabet dans l'ordre de classement. L'organisation des valeurs Python est géniale.
la source
Utiliser une logique
Utiliser une certaine logique de la vieille école pour pratiquer des entretiens.
la source
Vous pouvez également utiliser le complément au niveau du bit de l'index du tableau pour parcourir le tableau à l'envers:
Quoi que vous fassiez, ne le faites pas de cette façon.
la source
Utilisez la compréhension de la liste:
la source
Une autre solution serait d'utiliser numpy.flip pour cela
la source
À strictement parler, la question n'est pas de savoir comment retourner une liste en sens inverse, mais plutôt comment inverser une liste avec un exemple de nom de liste
array
.Pour inverser une liste nommée,
"array"
utilisezarray.reverse()
.La méthode de découpage incroyablement utile telle que décrite peut également être utilisée pour inverser une liste en place en définissant la liste comme une modification découpée d'elle-même en utilisant
array = array[::-1]
.la source
array[:] = array[::-1]
la source
Avec un minimum de fonctions intégrées, en supposant que ce sont les paramètres de l'entretien
la source
La traduction la plus directe de votre besoin en Python est cette
for
déclaration:C'est plutôt cryptique mais peut être utile.
la source
la source
//
opérateur de division de plancher.Vous pouvez toujours traiter la liste comme une pile en faisant simplement ressortir les éléments du haut de la pile à l'arrière de la liste. De cette façon, vous profitez des caractéristiques du premier entré, dernier sorti d'une pile. Bien sûr, vous consommez le 1er tableau. J'aime cette méthode dans la mesure où elle est assez intuitive dans la mesure où vous voyez une liste consommée par le back-end tandis que l'autre est construite par le front-end.
la source
la source
utilisation
la source
Voici un moyen d'évaluer paresseusement l'inverse à l'aide d'un générateur :
Maintenant, parcourez comme ceci:
Si vous avez besoin d'une liste:
la source
Il existe 3 méthodes pour obtenir la liste inversée:
Méthode de découpage 1:
reversed_array = array[-1::-1]
Méthode de découpage 2:
reversed_array2 = array[::-1]
Utilisation de la fonction intégrée:
reversed_array = array.reverse()
La troisième fonction a en fait inversé l'objet de liste en place. Cela signifie qu'aucune copie des données intactes n'est conservée. C'est une bonne approche si vous ne souhaitez pas conserver l'ancienne version. Mais cela ne semble pas être une solution si vous voulez la version vierge et inversée.
la source
la source
l[::-1]
, et en même temps beaucoup moins lisible. La programmation fonctionnelle en Python est malheureusement assez lente.