Réponses:
Vous pouvez utiliser la reversed
fonction pour cela comme:
>>> array=[0,10,20,40]
>>> for i in reversed(array):
... print(i)
Notez que reversed(...)
cela ne renvoie pas de liste. Vous pouvez obtenir une liste inversée en utilisant list(reversed(array))
.
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!
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
La syntaxe de tranche étendue est bien expliquée dans l' entrée Quoi de neuf Python pour publication2.3.5
Sur demande spéciale dans un commentaire, il s'agit de la documentation de tranche la plus récente .
reversed
renvoie un listreverseiterator
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]
>>> L = [0,10,20,40]
>>> L.reverse()
>>> L
[40, 20, 10, 0]
Ou
>>> L[::-1]
[40, 20, 10, 0]
L=L[::-1]
d'inverser réellement la liste, sinon vous ne retournez que les valeurs en sens inverse
b = l[-n:] b.reverse() l = b + l[:len(l) - n]
Je pense que la meilleure façon d'inverser une liste en Python est de faire:
a = [1,2,3,4]
a = a[::-1]
print(a)
>>> [4,3,2,1]
Le travail est terminé et vous avez maintenant une liste inversée.
Pour inverser la même liste, utilisez:
array.reverse()
Pour affecter une liste inversée à une autre liste, utilisez:
newArray = array[::-1]
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 required
for 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 pointer
print "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 list
print 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.
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 que first10 = 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é 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
liste
l = list(range(1000000))
Timings Python 3.5
timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44
Timings Python 2.7
timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46
list.reverse
est le plus rapide, car il s'inverse sur place
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 list
dans 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 reversed
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ée list
, c'est mieux dans de nombreux cas. La perte pour reversed
est faible (~ 1/6 de plus que list.reverse()
).
>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]
array=[0,10,20,40]
for e in reversed(array):
print e
L'utilisation inversée (tableau) serait probablement la meilleure voie.
>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>> print item
Si vous avez besoin de comprendre comment cela pourrait être mis en œuvre sans utiliser le intégré reversed
.
def reverse(a):
midpoint = len(a)/2
for item in a[:midpoint]:
otherside = (len(a) - a.index(item)) - 1
temp = a[otherside]
a[otherside] = a[a.index(item)]
a[a.index(item)] = temp
return a
Cela devrait prendre du temps O (N).
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]
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)
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
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.
def rev_slice(mylist):
a = mylist[::-1]
return a
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.
def reversed_iterator(mylist):
a = reversed(mylist)
return a
def reversed_with_list(mylist):
a = list(reversed(mylist))
return a
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) - 1
return [ 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 -10
return [ mylist[-index-1] for index in range(len(mylist)) ]
def rev_manual_index_loop(mylist):
a = []
reverse_index = len(mylist) - 1
for 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
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 < 15 else ''
# 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))
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))
Production:
Time: 0.00489711761475 s
Time: 0.00609302520752 s
timeit
.
En Python, l'ordre des listes peut également être manipulé avec le tri , organisant vos variables dans l'ordre numérique / alphabétique:
print(sorted(my_list))
my_list.sort(), print(my_list)
Vous pouvez trier avec le drapeau "reverse = True" :
print(sorted(my_list, reverse=True))
ou
my_list.sort(reverse=True), print(my_list)
Vous ne souhaitez peut-être pas trier les valeurs, mais uniquement inverser les valeurs. Ensuite, nous pouvons le faire comme ceci:
print(list(reversed(my_list)))
** Les nombres ont priorité sur l'alphabet dans l'ordre de classement. L'organisation des valeurs Python est géniale.
Utiliser une certaine logique de la vieille école pour pratiquer des entretiens.
Permutation des numéros d'avant en arrière. Utilisation de deux pointeurs
index[0] and index[last]
def reverse(array):
n = array
first = 0
last = len(array) - 1
while first < last:
holder = n[first]
n[first] = n[last]
n[last] = holder
first += 1
last -= 1
return n
input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 1, 2, 3, 4, 5, -1]
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.
Une autre solution serait d'utiliser numpy.flip pour cela
import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]
À 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]
.
array[:] = array[::-1]
def reverse(text):
output = []
for i in range(len(text)-1, -1, -1):
output.append(text[i])
return output
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 -= 1
print(inverse)
La traduction la plus directe de votre besoin en Python est cette for
déclaration:
for i in xrange(len(array) - 1, -1, -1):
print i, array[i]
C'est plutôt cryptique mais peut être utile.
def reverse(my_list):
L = len(my_list)
for i in range(L/2):
my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
return my_list
//
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.
>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
nl.append(l.pop())
>>> print nl
[6, 5, 4, 3, 2, 1]
list_data = [1,2,3,4,5]
l = len(list_data)
i=l+1
rev_data = []
while l>0:
j=i-l
l-=1
rev_data.append(list_data[-j])
print "After Rev:- %s" %rev_data
utilisation
print(reversed(list_name))
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
Maintenant, parcourez comme ceci:
for x in reverse([1, 2, 3]):
print(x)
Si vous avez besoin d'une liste:
l = list(reverse([1, 2, 3]))
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.