105 votes

Le meilleur moyen de créer une liste "inversée" en Python?

En Python, ce qui est la meilleure façon de créer une nouvelle liste dont les éléments sont les mêmes que ceux de quelques autres de la liste, mais dans l'ordre inverse? (Je ne veux pas modifier la liste existante en place.)

Voici une solution qui a été apportée à moi:

new_list = list(reversed(old_list))

Il est également possible de dupliquer old_list puis d'inverser le dupliquer en place:

new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()

Est-il une meilleure option que j'ai négligé? Si non, est-il une raison impérieuse (tels que l'efficacité) pour utiliser l'une des méthodes ci-dessus sur l'autre?

233voto

Alex Martelli Points 330805
newlist = oldlist[::-1]

L' [::-1] découpage (mon épouse Anna aime à appeler "le Martien smiley";-) signifie: tranche de l'ensemble de la séquence, par pas de -1, c'est à dire, dans le sens inverse. Il fonctionne pour toutes les séquences.

Notez que cela (et les alternatives que vous avez mentionné) est l'équivalent d'une "copie", c'est à dire: si les articles sont mutables et que vous appelez des mutateurs sur eux, les mutations dans les articles figurant dans la liste d'origine sont également dans les éléments de la liste inversée, et vice versa. Si vous avez besoin pour éviter cela, une copy.deepcopy (tout en toujours une opération coûteuse), suivie dans ce cas par un .reverse, est la seule bonne option.

65voto

sdolan Points 15572

Maintenant, passons à timeit . Astuce: Alex's [::-1] est le plus rapide :)

 $ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))"
100000 loops, best of 3: 2.34 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();"
1000000 loops, best of 3: 0.686 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];"
1000000 loops, best of 3: 0.569 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];"
1000000 loops, best of 3: 1.48 usec per loop


$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 44.7 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();"
10000 loops, best of 3: 27.2 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];"
10000 loops, best of 3: 24.3 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];"
10000 loops, best of 3: 155 usec per loop
 

Mise à jour: Ajout d'une méthode de composition de liste suggérée par inspectorG4dget. Je laisserai les résultats parler d'eux-mêmes.

11voto

mekarpeles Points 101

Des ajustements

Il vaut la peine de fournir une base de référence et / ou le réglage de la timeit calculs par sdolan qui montrent la performance de "inversé" sans la souvent inutiles liste() de conversion. Cette liste() ajoute un supplément de 26 usecs à l'exécution et n'est nécessaire que dans le cas d'un itérateur est inacceptable.

Résultats:

reversed(lst) -- 11.2 uses

lst[::-1] --23.6 secs

Calculs:

# I ran this set of 100000 and came up with 11.2, twice:
python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)"
100000 loops, best of 3: 11.2 usec per loop

python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)"
100000 loops, best of 3: 11.2 usec per loop

# This shows the overhead of list()
python -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 37.1 usec per loop

# This is the result for reverse via -1 step slices
python -m timeit "ol = [1, 2, 3]*1000;nl = ol[::-1]"
10000 loops, best of 3: 23.6 usec per loop

Conclusions:

La conclusion de ces tests est inversé() est plus rapide que la tranche [::-1] par 12.4 usecs

-1voto

inspectorG4dget Points 25092

Peut-être que ce que vous recherchez est:

 new_list = [i for i in reversed(old_list)]
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X