Qu'en est-il de [* plage (9, -1, -1)]? Super pythonique!
onofricamila
Réponses:
561
utiliser la reversed()fonction:
reversed(range(10))
C'est beaucoup plus significatif.
Mise à jour:
Si vous voulez que ce soit une liste (comme l'a souligné btk):
list(reversed(range(10)))
Mise à jour:
Si vous souhaitez utiliser uniquement rangepour obtenir le même résultat, vous pouvez utiliser tous ses paramètres.range(start, stop, step)
Par exemple, pour générer une liste [5,4,3,2,1,0], vous pouvez utiliser les éléments suivants:
range(5,-1,-1)
C'est peut-être moins intuitif mais comme les commentaires le mentionnent, c'est plus efficace et la bonne utilisation de la plage pour la liste inversée.
Bien qu'il «soit» moins efficace. Et vous ne pouvez pas y trancher.
Jakob Bowyer
6
Cette réponse est très claire et facile à comprendre, mais elle doit l'être range(10), non range(9). De plus, si vous voulez une liste complète (pour le découpage, etc.), vous devriez le faire list(reversed(range(10))).
John Y
5
Cela produit un itérateur, OP a demandé un résultat sous forme de liste.
btk
6
L'utilisation de "inversé" avec le générateur python (en supposant que nous parlons de la gamme Python 3 intégrée) est juste conceptuellement erronée et enseigne de mauvaises habitudes de ne pas prendre en compte la complexité de la mémoire / du traitement lors de la programmation dans un langage de haut niveau.
thedk
7
En Python3, reversedn'accepte pas les générateurs en général mais il accepte range. Pourquoi aurait-il reversed(range(10000))besoin d'allouer de la mémoire à toute la liste? rangepeut renvoyer un objet qui implémente la __reversed__méthode qui permet une itération inverse efficace?
avmohan
312
Utilisez la fonction intégrée «gamme». La signature est range(start, stop, step). Cela produit une séquence qui donne des nombres, commençant par start, et se terminant si stopa été atteint, à l'exclusion stop.
En Python 3, cela produit un rangeobjet non-liste , qui fonctionne efficacement comme une liste en lecture seule (mais utilise beaucoup moins de mémoire, en particulier pour les grandes plages).
Pouvez-vous s'il vous plaît expliquer cela aussi, pouvez-vous également me recommander n'importe quel site Web / livre pdf pour python
ramesh.mimit
8
@ramesh Si vous exécutez help(range)dans un shell python, il vous indiquera les arguments. Ils sont le nombre pour commencer, le nombre pour terminer (exclusif) et l'étape à prendre, donc il commence à 9 et soustrait 1 jusqu'à ce qu'il atteigne -1 (à quel moment il s'arrête sans revenir, c'est pourquoi la plage se termine à 0)
Michael Mrozek
3
@ ramesh.mimit: Accédez simplement au site officiel de Python. Il y a une documentation complète, y compris un excellent tutoriel.
John Y
5
Vraiment, c'est la bonne réponse, mais cela pourrait être expliqué plus clairement. range(start, stop, step) - commencez par le nombre startet donnez des résultats à moins d' stopavoir été atteints, en vous déplaçant à stepchaque fois.
M. B
43
Vous pouvez utiliser range(10)[::-1]ce qui est la même chose range(9, -1, -1)et sans doute plus lisible (si vous êtes familier avec l' sequence[::-1]idiome Python commun ).
Pour ceux qui sont intéressés par "l'efficacité" des options collectées jusqu'à présent ...
La réponse de Jaime RGP m'a amené à redémarrer mon ordinateur après avoir chronométré la solution quelque peu "difficile" de Jason suivant littéralement ma propre suggestion (via un commentaire). Pour épargner aux curieux d'entre vous les temps d'arrêt, je vous présente ici mes résultats (les pires-premiers):
Aucun sens à utiliser reversecar la méthode range peut retourner une liste inversée.
Lorsque vous avez une itération sur n éléments et que vous souhaitez remplacer l'ordre de liste renvoyé par range(start, stop, step)vous devez utiliser le troisième paramètre de la plage qui l'identifie stepet le définir -1, les autres paramètres doivent être ajustés en conséquence:
Fournir arrêt paramètre comme -1(sa valeur précédente stop - 1, stopétait égal à 0).
En tant que paramètre de démarrage, utilisez n-1.
Donc, l'équivalent de la plage (n) dans l'ordre inverse serait:
Franchement, je trouve cela moins intuitif quereversed(range(n))
Nicholas Hamilton
1
@NicholasHamilton D'accord avec vous, mais l'idée derrière cette réponse est d'utiliser moins de ressources ... (et la question portait sur l'utilisation de la fonction de plage juste :))
Andriy Ivaneyko
Ok, pas de soucis, je suppose que cela dépend de la situation. Par exemple, si la fonction de plage est utilisée comme index pour une boucle, alors elle aura un effet limité, cependant, si elle est utilisée à l'intérieur d'une boucle externe, alors le coût sera composé ...
Nicholas Hamilton
8
La lisibilité mise à part, reversed(range(n))semble être plus rapide que range(n)[::-1].
$ python -m timeit "reversed(range(1000000000))"1000000 loops, best of 3:0.598 usec per loop
$ python -m timeit "range(1000000000)[::-1]"1000000 loops, best of 3:0.945 usec per loop
bon d'avoir quelques chiffres :) - pourquoi n'avez-vous pas ajouté range(1000000000-1,-1,-1)aussi?
Wolf
... mieux vaut ne pas essayer timeit range(1000000000-1,-1,-1)sur la ligne de commande, voir plutôt mes résultats :-)
Wolf
6
L'exigence de cette question appelle un nombre listentier de taille 10 dans l'ordre décroissant. Produisons donc une liste en python.
# This meets the requirement.# But it is a bit harder to wrap one's head around this. right?>>> range(10-1,-1,-1)[9,8,7,6,5,4,3,2,1,0]# let's find something that is a bit more self-explanatory. Sounds good?# ----------------------------------------------------# This returns a list in ascending order.# Opposite of what the requirement called for.>>> range(10)[0,1,2,3,4,5,6,7,8,9]# This returns an iterator in descending order.# Doesn't meet the requirement as it is not a list.>>> reversed(range(10))<listreverseiterator object at 0x10e14e090># This returns a list in descending order and meets the requirement>>> list(reversed(range(10)))[9,8,7,6,5,4,3,2,1,0]
J'aime vraiment le triple-1 C'est exactement ce modèle qui le rend facile à conserver wrap one's head around this- Aujourd'hui, j'ai appris que s'il doit vraiment être efficace , utilisez-le range(n-1, -1, -1)lorsque vous parcourez une plage dans l'ordre inverse.
Wolf
5
Vous pouvez imprimer des nombres inversés avec range () BIF Like,
for number in range (10,0,-1):print( number )
La production sera [10,9,8,7,6,5,4,3,2,1]
range () - plage (début, fin, incrément / décrément) où début est inclusif, fin est exclusif et incrémenter peut être n'importe quel nombre et se comporte comme pas
Très souvent, la question est de savoir si range(9, -1, -1)mieux qu'en reversed(range(10))Python 3? Les personnes qui ont travaillé dans d'autres langues avec des itérateurs ont immédiatement tendance à penser que reverse () doit mettre en cache toutes les valeurs, puis revenir dans l'ordre inverse. Le fait est que l' reversed()opérateur de Python ne fonctionne pas si l'objet n'est qu'un itérateur. L'objet doit avoir l'un des deux suivants pour que reverse () fonctionne:
Soit la prise en charge len()et les index entiers via[]
Ou avoir __reversed__()implémenté la méthode.
Si vous essayez d'utiliser reverse () sur un objet qui n'a rien de ci-dessus, vous obtiendrez:
>>>[reversed((x for x in range(10)))]TypeError:'generator' object isnot reversible
Donc, en bref, Python reversed()est uniquement destiné aux objets de type tableau et devrait donc avoir les mêmes performances que l'itération directe.
Mais qu'en est-il range()? N'est-ce pas un générateur? En Python 3, il est générateur mais enveloppé dans une classe qui implémente les deux ci-dessus. range(100000)Ne prend donc pas beaucoup de mémoire, mais il prend toujours en charge l'indexation et l'inversion efficaces.
Donc, en résumé, vous pouvez utiliser reversed(range(10))sans aucun impact sur les performances.
Votre réponse montre pourquoi reversed(range(10))est moins sujet aux erreurs. Pas d'infraction Asinox. Juste une observation honnête.
Michał Šrajer
Je ne sais pas s'il est normal de laisser des réponses erronées affichées. Puis-je ou quelqu'un le corriger ou même le supprimer?
sinekonata
3
@sine, non, laissez-le simplement et demandez-vous comment il a accumulé 3 votes positifs ... Je suppose que vous pouvez le signaler à l'attention du modérateur (duplicata de la réponse de 18 mois plus tôt sauf cassé), pas sûr qu'ils le suppriment ou non.
Vous n'avez pas nécessairement besoin d'utiliser la fonction range, vous pouvez simplement faire list [:: - 1] qui devrait retourner rapidement la liste dans l'ordre inverse, sans utiliser d'ajouts.
Cela semble être la solution suggérée dans une réponse précédente . Il semble également que vous essayiez de commenter une réponse précédente différente - vous devrez obtenir un peu plus de réputation avant de pouvoir le faire.
Grisha Levit
1
Supposons que vous ayez une liste appelez-la a = {1,2,3,4,5} Maintenant, si vous voulez imprimer la liste en sens inverse, utilisez simplement le code suivant.
a.reverse
for i in a:print(i)
Je sais que vous avez demandé à l'aide de la plage, mais il a déjà répondu.
vous n'obtiendrez pas un cas 0. Par exemple, supposons que votre 10 n'est pas un nombre magique et qu'une variable que vous utilisez pour rechercher commence à l'envers. Si votre cas n est 0, inversé (plage (0)) ne s'exécutera pas, ce qui est faux si vous avez par hasard un seul objet dans l'index zéro.
Je pensais que beaucoup (comme moi) pourraient être plus intéressés par un cas courant de traverser une liste existante dans un ordre inversé à la place, comme cela est indiqué dans le titre, plutôt que de simplement générer des indices pour une telle traversée.
Même si toutes les bonnes réponses sont toujours parfaitement correctes dans ce cas, je tiens à souligner que la comparaison des performances effectuée dans la réponse de Wolf concerne uniquement la génération d'indices. J'ai donc fait un benchmark similaire pour parcourir une liste existante dans l'ordre inverse.
%timeit [a[i]for i in range(9,-1,-1)]1.09µs ±11.1 ns per loop (mean ± std. dev. of 7 runs,1000000 loops each)
Comme vous le voyez, dans ce cas, il n'est pas nécessaire de générer explicitement des indices, donc la méthode la plus rapide est celle qui fait le moins d'actions supplémentaires.
NB: J'ai testé dans JupyterLab qui a une "commande magique" pratique %timeit. Il utilise standard timeit.timeitsous le capot. Testé pour Python 3.7.3
Réponses:
utiliser la
reversed()
fonction:C'est beaucoup plus significatif.
Mise à jour:
Si vous voulez que ce soit une liste (comme l'a souligné btk):
Mise à jour:
Si vous souhaitez utiliser uniquement
range
pour obtenir le même résultat, vous pouvez utiliser tous ses paramètres.range(start, stop, step)
Par exemple, pour générer une liste
[5,4,3,2,1,0]
, vous pouvez utiliser les éléments suivants:C'est peut-être moins intuitif mais comme les commentaires le mentionnent, c'est plus efficace et la bonne utilisation de la plage pour la liste inversée.
la source
range(10)
, nonrange(9)
. De plus, si vous voulez une liste complète (pour le découpage, etc.), vous devriez le fairelist(reversed(range(10)))
.reversed
n'accepte pas les générateurs en général mais il accepterange
. Pourquoi aurait-ilreversed(range(10000))
besoin d'allouer de la mémoire à toute la liste?range
peut renvoyer un objet qui implémente la__reversed__
méthode qui permet une itération inverse efficace?Utilisez la fonction intégrée «gamme». La signature est
range(start, stop, step)
. Cela produit une séquence qui donne des nombres, commençant parstart
, et se terminant sistop
a été atteint, à l'exclusionstop
.En Python 3, cela produit un
range
objet non-liste , qui fonctionne efficacement comme une liste en lecture seule (mais utilise beaucoup moins de mémoire, en particulier pour les grandes plages).la source
help(range)
dans un shell python, il vous indiquera les arguments. Ils sont le nombre pour commencer, le nombre pour terminer (exclusif) et l'étape à prendre, donc il commence à 9 et soustrait 1 jusqu'à ce qu'il atteigne -1 (à quel moment il s'arrête sans revenir, c'est pourquoi la plage se termine à 0)range(start, stop, step)
- commencez par le nombrestart
et donnez des résultats à moins d'stop
avoir été atteints, en vous déplaçant àstep
chaque fois.Vous pouvez utiliser
range(10)[::-1]
ce qui est la même choserange(9, -1, -1)
et sans doute plus lisible (si vous êtes familier avec l'sequence[::-1]
idiome Python commun ).la source
Pour ceux qui sont intéressés par "l'efficacité" des options collectées jusqu'à présent ...
La réponse de Jaime RGP m'a amené à redémarrer mon ordinateur après avoir chronométré la solution quelque peu "difficile" de Jason suivant littéralement ma propre suggestion (via un commentaire). Pour épargner aux curieux d'entre vous les temps d'arrêt, je vous présente ici mes résultats (les pires-premiers):
Réponse de Jason (peut-être juste une excursion dans le pouvoir de la compréhension de liste ):
réponse de martineau (lisible si vous connaissez la syntaxe des tranches étendues ):
Réponse de Michał Šrajer (celle acceptée, très lisible):
réponse de bene (la toute première, mais très sommaire à l'époque ):
La dernière option est facile à retenir en utilisant la
range(n-1,-1,-1)
notation de Val Neekman .la source
va résoudre ce problème. Il affichera 8 à 1, et -1 signifie une liste inversée
la source
Aucun sens à utiliser
reverse
car la méthode range peut retourner une liste inversée.Lorsque vous avez une itération sur n éléments et que vous souhaitez remplacer l'ordre de liste renvoyé par
range(start, stop, step)
vous devez utiliser le troisième paramètre de la plage qui l'identifiestep
et le définir-1
, les autres paramètres doivent être ajustés en conséquence:-1
(sa valeur précédentestop - 1
,stop
était égal à0
).n-1
.Donc, l'équivalent de la plage (n) dans l'ordre inverse serait:
la source
reversed(range(n))
La lisibilité mise à part,
reversed(range(n))
semble être plus rapide querange(n)[::-1]
.Juste si quelqu'un se demandait :)
la source
range(1000000000-1,-1,-1)
aussi?timeit range(1000000000-1,-1,-1)
sur la ligne de commande, voir plutôt mes résultats :-)L'exigence de cette question appelle un nombre
list
entier de taille 10 dans l'ordre décroissant. Produisons donc une liste en python.la source
-1
C'est exactement ce modèle qui le rend facile à conserverwrap one's head around this
- Aujourd'hui, j'ai appris que s'il doit vraiment être efficace , utilisez-lerange(n-1, -1, -1)
lorsque vous parcourez une plage dans l'ordre inverse.Vous pouvez imprimer des nombres inversés avec range () BIF Like,
La production sera [10,9,8,7,6,5,4,3,2,1]
range () - plage (début, fin, incrément / décrément) où début est inclusif, fin est exclusif et incrémenter peut être n'importe quel nombre et se comporte comme pas
la source
Très souvent, la question est de savoir si
range(9, -1, -1)
mieux qu'enreversed(range(10))
Python 3? Les personnes qui ont travaillé dans d'autres langues avec des itérateurs ont immédiatement tendance à penser que reverse () doit mettre en cache toutes les valeurs, puis revenir dans l'ordre inverse. Le fait est que l'reversed()
opérateur de Python ne fonctionne pas si l'objet n'est qu'un itérateur. L'objet doit avoir l'un des deux suivants pour que reverse () fonctionne:len()
et les index entiers via[]
__reversed__()
implémenté la méthode.Si vous essayez d'utiliser reverse () sur un objet qui n'a rien de ci-dessus, vous obtiendrez:
Donc, en bref, Python
reversed()
est uniquement destiné aux objets de type tableau et devrait donc avoir les mêmes performances que l'itération directe.Mais qu'en est-il
range()
? N'est-ce pas un générateur? En Python 3, il est générateur mais enveloppé dans une classe qui implémente les deux ci-dessus.range(100000)
Ne prend donc pas beaucoup de mémoire, mais il prend toujours en charge l'indexation et l'inversion efficaces.Donc, en résumé, vous pouvez utiliser
reversed(range(10))
sans aucun impact sur les performances.la source
je crois que cela peut aider,
ci-dessous est Utilisation:
la source
la source
reversed(range(10))
est moins sujet aux erreurs. Pas d'infraction Asinox. Juste une observation honnête.Utilisation sans [:: - 1] ou inversé -
la source
"python!"[::-1]
?la source
Vous n'avez pas nécessairement besoin d'utiliser la fonction range, vous pouvez simplement faire list [:: - 1] qui devrait retourner rapidement la liste dans l'ordre inverse, sans utiliser d'ajouts.
la source
Supposons que vous ayez une liste appelez-la a = {1,2,3,4,5} Maintenant, si vous voulez imprimer la liste en sens inverse, utilisez simplement le code suivant.
Je sais que vous avez demandé à l'aide de la plage, mais il a déjà répondu.
la source
Est la bonne forme. Si tu utilises
vous n'obtiendrez pas un cas 0. Par exemple, supposons que votre 10 n'est pas un nombre magique et qu'une variable que vous utilisez pour rechercher commence à l'envers. Si votre cas n est 0, inversé (plage (0)) ne s'exécutera pas, ce qui est faux si vous avez par hasard un seul objet dans l'index zéro.
la source
Je pensais que beaucoup (comme moi) pourraient être plus intéressés par un cas courant de traverser une liste existante dans un ordre inversé à la place, comme cela est indiqué dans le titre, plutôt que de simplement générer des indices pour une telle traversée.
Même si toutes les bonnes réponses sont toujours parfaitement correctes dans ce cas, je tiens à souligner que la comparaison des performances effectuée dans la réponse de Wolf concerne uniquement la génération d'indices. J'ai donc fait un benchmark similaire pour parcourir une liste existante dans l'ordre inverse.
TL; DR
a[::-1]
est le plus rapide.Conditions préalables:
Réponse de Jason :
réponse de martineau :
Réponse de Michał Šrajer :
réponse de bene :
Comme vous le voyez, dans ce cas, il n'est pas nécessaire de générer explicitement des indices, donc la méthode la plus rapide est celle qui fait le moins d'actions supplémentaires.
NB: J'ai testé dans JupyterLab qui a une "commande magique" pratique
%timeit
. Il utilise standardtimeit.timeit
sous le capot. Testé pour Python 3.7.3la source